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

发布于 2024-09-29 04:10:06 字数 8126 浏览 2 评论 0原文

我有一个 C# dll,想在 VB.NET 中使用它。我正在使用 C# 2008 Express 和 VB 2008 Express。我在 VB 项目中添加了对 C# dll 的引用。当我在 C# dll 中创建类的实例时,它给出以下错误消息:“类型‘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

I have a C# dll and want to use it in VB.NET. I'm using C# 2008 Express and VB 2008 Express. I have added a reference in a VB project to the C# dll. When I create an instane of a class in the C# dll, it gives the following error messsage: "Type 'RF.RabinFingerprint' has no constructors". How do I fix this?

My C# dll 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 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]);
        }
    }
}

My VB code:

Imports RF

Module Module1

    Sub Main()

        Dim t As New RabinFingerprint

    End Sub

End Module

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

苍风燃霜 2024-10-06 04:10:06

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

有关 VB.Net 和 C# 中 static/shared 之间差异的信息此处 这可能有助于解决这个问题。

如果您在 C# 中执行此操作,则只需调用类的静态方法,例如

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

等。

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

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

这是一个 来自 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'      

If you want to use instances, you need to add a non-static constructor to the C# class - currently it's only got a static constructor.

There is info on diffs between static/shared in VB.Net and C# here that could be useful in resolving this.

If you were doing this in C# you just call the class's static methods like

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

etc.

In VB.Net this looks something like this:

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

Here is an example from MSDN of what I mean. Here both Console.WriteLine and Regex.Split are static, just like your class's methods.

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'      
葬心 2024-10-06 04:10:06

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

You have no constructors because your class is declared as static

强辩 2024-10-06 04:10:06

您是否尝试过在 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

史蒂夫是对的。如果您的类被设计为静态,因为其中的所有内容都是静态的,那么必须更改的是对构造函数的调用。由于该类是静态的,因此您无法创建该类的实例。

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

Have you tried to use it from C#?

It probably gives you the same error there.

EDIT

I have tried your code. (Jeff we need a copy source code button)

IN VB.NET. There's the following error:

Type 'RF.RabinFingerprint' has no constructors.

In C# you get the following 2 errors.

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

Actually C# shows you the real problem. As Jazz have mentioned. You should change your class to be nonstatic to work properly

EDIT2

Steve is right. If your class has been designed to be static as it appears since everything in there is static, then what has to be changed is the call to the constructor. Since the class is static you can't create an instance of your class.

There is no need to call the constructor because it will be automatically called the first time the class is used (For example when you call a method from it).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文