C#中的C ++方法声明

时间:2017-12-30 12:47:58

标签: c# c++ interop

非托管dll的以下C ++方法的C#声明是什么:

long WINAPI MT123_GetVersion(HANDLE hComHandle, BYTE *Version, int &len);

long __stdcall MT123_GetStatus(HANDLE hComHandle, BYTE *Saddr, BYTE &status)

long __stdcall MT123_GetTagData(HANDLE hComHandle, BYTE *Saddr,BYTE &status,
BYTE *Data, int &len);
带有DllImport属性的

1 个答案:

答案 0 :(得分:1)

一般来说:

long WINAPI MT123_GetVersion(HANDLE hComHandle, BYTE *Version, int &len);

变为:

int MT123_GetVersion(IntPtr hComHandle, IntPtr pVersionBuffer, ref int len)

必须使用pVersionBuffer初始化Marshal.AllocCoTaskMem参数。您应该使用Marshal.Copy将数据复制到托管数组,然后使用Marshal.FreeCoTaskMem释放缓冲区。

我建议你写一个包装函数来管理细节。例如

  • 你需要分配多少内存:这是你调用该函数两次的那个,第一次通过null来检索长度?或者它是否具有合理的最大尺寸,您可以进行硬编码?
  • 返回值的含义是什么:这是一个错误代码,你应该变成一个例外吗?

E.g:

byte[] GetVersionWrapper(IntPtr hComHandle)
{
    IntPtr pVersionBuffer = IntPtr.Zero;

    try
    {
      int len = 0;
      // First retrieve the length
      int status = MT123_GetVersion(hComHandle, IntPtr.Zero, ref len);
      if(status != 0) throw new Exception("message here");
      if(len < 0 || len > 1024) throw new Exception("message here");
      // Now allocate a buffer of the given length.
      pVersionBuffer = Marshal.AllocCoTaskMem(len);
      // Now retrieve the version information into the buffer
      int status = MT123_GetVersion(hComHandle, pVersionBuffer, ref len);
      if(status != 0) throw new Exception("message here");
      // Now copy the version information to a managed array.
      byte[] retVal = new byte[len];
      Marshal.Copy(pVersionBuffer, retVal, 0, len);
      // Return the managed array.
      return retVal;
    }
    finally
    {
      // done in Finally in case anything above throws an exception.
      Marshal.FreeCoTaskMem(pVersionBuffer);
    }
}