2010-10-28 74 views
2

我有一个C#的DLL,并希望在VB.NET中使用它。我正在使用C#2008 Express和VB 2008 Express。我已经在VB项目中添加了一个引用到C#dll。当我在C#dll中创建类的实例时,它会给出以下错误消息:“类型'RF.RabinFingerprint'没有构造函数”。我该如何解决?如何从VB.Net调用C#类的静态方法?

我的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 

回答

1

你试过从C#中使用它?

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

编辑

我已经试过你的代码。 (Jeff we needs a 复制源代码按钮

在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

史蒂夫是正确的。如果你的类被设计为静态的,因为它里面的所有东西都是静态的,那么需要改变的是对构造函数的调用。由于该类是静态的,因此无法创建类的实例。

没有必要调用构造函数,因为它将在第一次使用该类时自动调用(例如,当您调用该方法时)。

+2

是否在.NET Framework类的静态方法不VB.Net支持访问,虽然声明为static?为什么要转换,如果整个静态是可取 – 2010-10-28 15:06:03

+0

@Steve,我编辑了你的评论的答案 – 2010-10-28 15:18:26

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'  
+0

它是'Dim result = RF.RabinFingerprint.ComputeFingerprint(...)' – 2010-10-28 15:09:30

+0

@Hans - 谢谢。这个工作是否会工作?它似乎应该。 – 2010-10-28 15:10:28

+0

是的,删除分号后。 – 2010-10-28 15:12:04

2

你有没有构造,因为你的类