如何存储UINT8_T*变量从C#中的C 返回

How to store a uint8_t* variable returned from a C++ function in c#?

本文关键字:变量 中的 返回 何存储 存储 UINT8      更新时间:2023-10-16

我正在从我的C#程序中调用C DLL。DLL由几个功能组成,我可以称其为大多数功能。

C 功能如下:

 __declspec(dllexport) uint8_t* myHash(const char *filename)
    {
         uint8_t *hash = (unsigned char*)malloc(72*sizeof(uint8_t));
         //some processing on hash  
         return hash;
    }

可以在上述代码中看到,哈希函数存储一个字符数组。我想在我的C#程序中收到值,但我无法做到。

我的C#代码如下:

 [DllImport("myHash.dll", CharSet = CharSet.Ansi)]
        public static extern IntPtr myHash(string filename);
    IntPtr ptr = myHash(fileA);
            char[] result = new char[72];
            Marshal.Copy(ptr, result, 0, 72);

问题是C#中的char是16位字符元素。您的C 代码返回8位uint8_t值的数组。您应该切换到使用字节数组。

[DllImport("myHash.dll", CallingConvention=CallingConvention.Cdecl,
    CharSet = CharSet.Ansi)]
public static extern IntPtr myHash(string filename);
....
IntPtr ptr = myHash(fileA);
byte[] result = new byte[72];
Marshal.Copy(ptr, result, 0, 72);

我指定了一个呼叫约定,因为,如书面,您的功能是__cdecl。也许您在问题的转录中省略了一些内容,但是上面的声明与问题中的无管理代码相匹配。

此功能的设计要好得多,允许呼叫者分配缓冲区。这避免了您必须从C 代码中导出Deallocator。我会像这样写C :

__declspec(dllexport) int myHash(const char *filename, uint8_t* hash)
{
     // calculate hash and copy to the provided buffer
     return 0; // return value is an error code
}

和相应的C#代码:

[DllImport("myHash.dll", CallingConvention=CallingConvention.Cdecl,
    CharSet = CharSet.Ansi)]
public static extern int myHash(string filename, byte[] hash);
....
byte[] hash = new byte[72];
int retval = myHash(fileA, hash);

此函数在其接口中进行硬编码,即缓冲区长度为72。这可能是合理的,但是也可以通过缓冲区的长度也有意义,以便无管理的代码可以防御缓冲区的超越。p>请注意,尽管您将此功能的输出称为字符数组,但使用uint8_t*的使用使其似乎更有可能是字节数组。如果确实是字符数组,则可以使用Encoding.GetString()转换为字符串。