如何从C向C#/.net返回字节

本文关键字:net 返回 字节 | 更新日期: 2023-09-27 18:24:25

这是我的C函数:

 DLL_PUBLIC void alve_ripemd320__finish(void* instance, uint32_t* out_hash)
 {
      ...
     for (uint32_t i=0, i_end=10; i<i_end; i++)
     {
         out_hash[i] = h[i]; 
     }
 }

以下是我如何从C#调用它:

 [DllImport(PlatformConstants.DllName)]
 static extern void alve_ripemd320__finish (IntPtr instance_space, ref byte[] hash);
 ...
 public byte[] Finish()
 {
     byte[] result = new byte[40];
     alve_ripemd320__finish (c_instance, ref result);
     return result;
 }

这会产生一个丑陋的SEGFAULT,如果我对上面写到out_hash的C代码进行注释,它就会消失。。。。我的问题是,这是使用PInvoke传递字节缓冲区的正确方式吗?

如何从C向C#/.net返回字节

您的C API正在写入无符号整数。我通常希望它被映射为:

[DllImport(PlatformConstants.DllName, CallingConvention=CallingConvention.Cdecl)]
static extern void alve_ripemd320__finish(IntPtr instance_space, uint[] hash);
public uint[] Finish()
{
   uint[] result = new uint[10];
   alve_ripemd320__finish (c_instance, ref result);
   return result;
}

这里有三个主要变化:

  1. 我将呼叫约定切换为Cdecl。这是C++编译器的标准(除非您在DLL_PUBLIC中明确切换到stdcall
  2. 我更改为匹配您的C API,它使用32位无符号整数而不是字节。但是,如果您选择的话,您应该能够切换回byte[]
  3. 你不需要经过ref。这通常等同于C API接受uint32_t** out_hash,而不是uint32_t* out_hash,后者应该直接映射到数组