tags:

views:

120

answers:

5

Could anyone please give me a short working example of a C# class which can be compiled to a DLL, and an example of VB.NET-code creating an object based on this class and using its members (methods). The C# class has to have a namespace, at least one class definition (obviously) and some methods or whatever they ought to be called. I have someone else's code of a C#-DLL but cannot see its members in my VB-project. I know I have to make a reference to the DLL in my VB.NET project. I'm using VB.NET Express 2008 and C# 2008 Express.

+5  A: 

Managed assemblies (DLLs and EXEs) are not "C#" or "VB.NET" or any other language.

They are .NET assemblies with CIL and should interoperate with any .NET language.

Once you reference such an assembly in your project, you have access to all public types in it.

If you can't see any of the members, make sure they are indeed declared as public, as C# will default to internal or private on most members.

Read more about access modifiers in C# here.

Oded
A: 

Would something like a C# to VB Converter work? If you have the code, and are comfortable with VB... work in VB.

This blog has an example of using C# as a class library in step 2. And a sample application.

WernerCD
I tried to convert it to VB but got some errors that I could not resolve. But please forget about that DLL, please give me a short example of something that actually works. From there I might be able to resolve my real issue.
iar
+2  A: 

My guess is that the members you are trying to access are just not declared public so they can't be used across namespaces.

If you want a working example, just create a new solution and follow below steps.

  1. Add a VB.net code project
  2. Add a public class.
  3. Add a C# Code project.
  4. Add a simple C# class.

When you have this setup, just make a project reference from one project to the other and try to call it in one of the created classes.

You can do this with any .Net dll as long as the members are declared public or the namespace is the same and the members are declared internal.

Peter
+9  A: 

--foo.cs

namespace Sharp
{
    public class Foo
    {
        public string Message
        {
            get { return "This is from CSharp"; }
        }
    }
}

--bar.vb

Namespace bartest
   Public Class Bar

     Public Shared Sub Main()
        Dim test as Sharp.Foo
        test = New Sharp.Foo()
        Console.WriteLine(test.Message)

     End Sub

  End Class
End Namespace

--batch file to compile

%WINDIR%\Microsoft.NET\Framework\v3.5\csc.exe /target:library foo.cs 
%WINDIR%\Microsoft.NET\Framework\v3.5\vbc.exe bar.vb /reference:foo.dll

--run bar.exe

daddyman
+1 for providing everything needed to run the test, even including the batch compilation command. Awesome.
wllmsaccnt
+1  A: 

Here is a working example - I had to rename some of your ComputeFingerprint overloads in the C# code to get VB.Net to correctly recognize the specific one you want called. Perhaps these are the errors you would not resolve that you mentioned above?

C# code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace RF
{

    /// <summary>
    /// Génère des empreintes de fichiers
    /// </summary>
    public static class RabinFingerprint
    {
        /// <summary>
        /// Bit 64 of the polynomial P is always 1 and not treated directly. This is the polynomial
        /// with the leading coefficient removed (lcr).
        /// Represents t^64 + t^4 + t^3 + t + 1.
        /// </summary>
        private static readonly UInt64 p_lcr = 0x000000000000001BL;
        /// <summary>
        /// It's not necessary to provide definitions for such integral constant variables as long as their
        /// addresses are not taken.
        /// Degree of the polynomial P.
        /// </summary>
        private static readonly int K = 64;
        /// <summary>
        /// Represents t^(K-1)
        /// </summary>
        private static readonly UInt64 T_K_minus_1 = (UInt64)1L << (K - 1);
        /// <summary>
        /// Broder's paper presents four pre-computed tables because words are considered to be 32-bit.
        /// In this implementation W is a 64-bit integral type. Eight tables are used.
        /// Table A is i1^127 + i2^126 + ... + i8^120.
        /// Table B is i1^119 + i2^118 + ... + i8^112.
        /// Table C, D, ..
        /// Table E is i1^95  + i2^94  + ... + i8^88. (This is table A in the paper.)
        /// Table F, G, H.
        /// </summary>
        private static UInt64[] tableA_ = new UInt64[256]; //Assuming byte size 8.
        private static UInt64[] tableB_ = new UInt64[256];
        private static UInt64[] tableC_ = new UInt64[256];
        private static UInt64[] tableD_ = new UInt64[256];
        private static UInt64[] tableE_ = new UInt64[256];
        private static UInt64[] tableF_ = new UInt64[256];
        private static UInt64[] tableG_ = new UInt64[256];
        private static UInt64[] tableH_ = new UInt64[256];
        /// <summary>
        /// Constructor
        /// </summary>
        static RabinFingerprint()
        {
            InitTables();
        }
        /// <summary>
        /// Initialize tables
        /// </summary>
        private static void InitTables()
        {
            //This represents t^(k + i) mod P, where i is the index of the array.
            //It will be used to compute the tables.
            UInt64[] mods = new UInt64[K];
            //Remember t^k mod P is equivalent to p_lcr.
            mods[0] = p_lcr;
            for (int i = 1; i < K; ++i)
            {
                //By property: t^i mod P = t(t^(i - 1)) mod P.
                mods[i] = mods[i - 1] << 1;
                //If mods[i - 1] had a term at k-1, mods[i] would have had the term k, which is not represented.
                //The term k would account for exactly one more division by P. Then, the effect is the same
                //as adding p_lcr to the mod.
                if ((mods[i - 1] & T_K_minus_1) != 0)
                    mods[i] ^= p_lcr;
            }
            //Compute tables. A control variable is used to indicate whether the current bit should be
            //considered.
            for (int i = 0; i < 256; ++i)
            {
                int control = i;
                for (int j = 0; j < 8 && control > 0; ++j)
                {
                    // bool.Parse(Convert.ToString())
                    if ((control & 1) == 1) //Ok, consider bit. ((byte))
                    {
                        tableA_[i] ^= mods[j + 56];
                        tableB_[i] ^= mods[j + 48];
                        tableC_[i] ^= mods[j + 40];
                        tableD_[i] ^= mods[j + 32];
                        tableE_[i] ^= mods[j + 24];
                        tableF_[i] ^= mods[j + 16];
                        tableG_[i] ^= mods[j + 8];
                        tableH_[i] ^= mods[j];
                    }
                    control >>= 1;
                }
            }
        }

        /// <summary>
        /// Compute hash key
        /// </summary>
        /// <param name="value">Value to hash</param>
        /// <returns>Value</returns>
        private static UInt64 ComputeTablesSum(ref UInt64 value)
        {
            value = tableH_[((value) & 0xFF)] ^
                    tableG_[((value >> 8) & 0xFF)] ^
                    tableF_[((value >> 16) & 0xFF)] ^
                    tableE_[((value >> 24) & 0xFF)] ^
                    tableD_[((value >> 32) & 0xFF)] ^
                    tableC_[((value >> 40) & 0xFF)] ^
                    tableB_[((value >> 48) & 0xFF)] ^
                    tableA_[((value >> 56) & 0xFF)];
            return value; //Pass by reference to return the same w. (Convenience and efficiency.)
        }
        /// <summary>
        /// Compute hask hey
        /// </summary>
        /// <param name="HashArray">Array of Ulong bytes to ahsh</param>
        /// <returns>Hash key</returns>
        private static UInt64 Compute(UInt64[] HashArray)
        {
            UInt64 w = 0L;
            for (int s = 0; s < HashArray.Length; ++s)
                w = ComputeTablesSum(ref w) ^ HashArray[s];
            return w;
        }
        /// <summary>
        /// Compute the fingerprint
        /// </summary>
        /// <param name="source">String to compute</param>
        /// <returns>Hash key</returns>
        public static UInt64 ComputeFingerPrint(string source)
        {
            byte[] table = Encoding.Unicode.GetBytes(source);
            UInt64[] values = new UInt64[table.LongLength];
            ConvertBytes(ref table, ref values);
            return Compute(values);
        }
        /// <summary>
        /// Compute the fingerprint, you must use this method for very large text
        /// </summary>
        /// <param name="source">String to compute</param>
        /// <returns>Hash key</returns>
        public static UInt64 ComputeFingerPrint2(ref string source)
        {
            return ComputeFingerPrint(source);
        }
        /// <summary>
        /// Compute the fingerprint, you must use this method for very large binary data
        /// </summary>
        /// <param name="source">Data to compute</param>
        /// <returns>Hash key</returns>
        public static UInt64 ComputeFingerPrint3(ref byte[] source)
        {
            UInt64[] values = new UInt64[source.LongLength];
            ConvertBytes(ref source, ref values);
            return Compute(values);
        }
        /// <summary>
        /// Compute the fingerprint, you must use this method for very large binary data
        /// </summary>
        /// <param name="source">Data to compute</param>
        /// <returns>Hash key</returns>
        public static UInt64 ComputeFingerPrint4(byte[] source)
        {
            return ComputeFingerPrint3(ref source);
        }
        /// <summary>
        /// Compute byte array to Uint64 array
        /// </summary>
        /// <param name="source">Table de byte source</param>
        /// <param name="destination">Tableau de Uin64</param>
        private static void ConvertBytes(ref byte[] source, ref UInt64[] destination)
        {
            for (long i = 0; i < source.LongLength; i++)
                destination[i] = Convert.ToUInt64(source[i]);
        }
    }
}

VB.Net code (tested, result = 8533825001260623604):

Imports RF

Module Module1

    Sub Main()

        Dim input = "this is the string"
        Dim result = RF.RabinFingerprint.ComputeFingerprint(input)

    End Sub

End Module
Steve Townsend