1

这是我的 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 传递字节缓冲区的正确方法吗?

4

1 回答 1

2

您的 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++ 编译器的标准(除非您明确切换到stdcallin DLL_PUBLIC)。
  2. 我更改为匹配您的 C API,它使用 32 位无符号整数而不是字节。byte[]但是,如果您选择,您应该能够切换回。
  3. 你应该不需要经过ref。这通常是 C API 接受uint32_t** out_hash, not的等价物uint32_t* out_hash,它应该直接映射到数组。
于 2013-07-23T18:53:23.900 回答