此C函数的正确C#PInvoke签名

时间:2012-07-24 21:35:29

标签: c# c++ windows-mobile pinvoke

我使用PInvoke Interop Assistant生成C#PInvoke签名。我想确认一下。我在调用DLL时收到“找不到PInvoke DLL”消息。我正在导出该功能。 DLL与可执行文件一起存在。消息和cipherText是原始字节的输入/输出blob,并且是相同的缓冲区。

extern "C" int __declspec(dllexport) EncryptDeviceName(uint8 *message, uint8 *ciphertext, uint64 msglength)
{
    ...

    return 0;
}

它生成了以下C#PInvoke签名:

   /// Return Type: int
   ///message: UINT8*
   ///ciphertext: UINT8*
   ///msglength: UINT64->unsigned __int64
   [DllImport("HC128.dll", EntryPoint = "EncryptDeviceName")]
   public static extern int EncryptDeviceName(System.IntPtr message, System.IntPtr     ciphertext, ulong msglength);

我会按照以下similar question中的建议进行操作并提供更新。

更新

我的签名在Windows CE 6上使用marshal alloc / dealloc。 Tergiver的签名也适用于Windows CE 6,它不需要编组alloc / dealloc。

2 个答案:

答案 0 :(得分:2)

你错过了CallingConvention.Cdecl。或者在C方使用__stdcall

答案 1 :(得分:0)

编写p / Invoke声明的方法有很多种。给定的一个可以使用,但是它需要你为它执行Marshaller的工作(分配非托管内存,复制和执行字符编码转换)。

该原生声明没有提供足够的信息来猜测所需的编组,这可能就是它不存在的原因。

本地函数在message中期望使用什么字符编码? ciphertext是一个原始字节的blob,还是有一个字符编码(in和out)?

<强>更新

如果messagecipherText都是原始字节数组,我们可以将它们编组为

[DllImport("HC128.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "EncryptDeviceName")]
 public static extern int EncryptDeviceName([In] byte[] message, [In, Out] byte[] ciphertext, ulong msglength);

In[Attribute]Out[Attribute]告诉编组人员执行复制的方式。 [In, Out]是默认值,我希望明确。