如何从VB.Net调用C#类的静态方法?

时间:2010-10-28 14:50:19

标签: c# vb.net dll reference

我有一个C#dll,想在VB.NET中使用它。我正在使用C#2008 Express和VB 2008 Express。我在VB项目中添加了一个引用到C#dll。当我在C#dll中创建一个类的instane时,它会给出以下错误消息:“Type'RF.RabinFingerprint'没有构造函数”。我该如何解决这个问题?

我的C#DLL代码:

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 ComputeFingerPrint(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 ComputeFingerPrint(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 ComputeFingerPrint(byte[] source)
        {
            return ComputeFingerPrint(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代码:

Imports RF

Module Module1

    Sub Main()

        Dim t As New RabinFingerprint

    End Sub

End Module

3 个答案:

答案 0 :(得分:7)

如果要使用实例,则需要向C#类添加非静态构造函数 - 目前它只有静态构造函数。

有关VB.Net和C#here中静态/共享之间的差异的信息可能有助于解决这个问题。

如果你在C#中这样做,你只需要调用类的静态方法,如

UInt64 result = RabinFingerprint.ComputeFIngerprint(...);

等。

在VB.Net中,这看起来像这样:

Dim result = RF.RabinFingerprint.ComputeFingerprint(...)

这是我的意思example from MSDN。这里Console.WriteLineRegex.Split都是静态的,就像你的类的方法一样。

Dim input As String = "plum--pear"
Dim pattern As String = "-"          ' Split on hyphens

Dim substrings() As String = Regex.Split(input, pattern)
For Each match As String In substrings
   Console.WriteLine("'{0}'", match)
Next
' The method writes the following to the console:
'    'plum'
'    ''
'    'pear'      

答案 1 :(得分:2)

您没有构造函数,因为您的类声明为静态

答案 2 :(得分:1)

您是否尝试过使用C#?

它可能会给你带来同样的错误。

修改

我已经尝试过您的代码了。 (杰夫,我们需要 复制源代码按钮

在VB.NET中。有以下错误:

Type 'RF.RabinFingerprint' has no constructors.

在C#中,您会收到以下2个错误。

Cannot create an instance of the static class 'RF.RabinFingerprint'
Cannot declare a variable of static type 'RF.RabinFingerprint'

实际上C#向您展示了真正的问题。正如爵士提到的那样。您应该将您的班级更改为非静态才能正常工作

<强> EDIT2

史蒂夫是对的。如果你的类被设计成静态的,因为它出现的东西都是静态的,那么必须改变的是对构造函数的调用。由于该类是静态的,因此无法创建类的实例。

无需调用构造函数,因为它将在第一次使用类时自动调用(例如,当您从中调用方法时)。