C# C++;C语言中的方法声明# 不管理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);

C# C++;C语言中的方法声明# 不管理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);,c#,c++,interop,C#,C++,Interop,使用DllImport属性?通常: long WINAPI MT123_GetVersion(HANDLE hComHandle, BYTE *Version, int &len); 变成: int MT123_GetVersion(IntPtr hComHandle, IntPtr pVersionBuffer, ref int len) 必须使用Marshal.allocTaskMem初始化pVersionBuffer参数。您应该使用Marshal.Copy将数据复制到托管阵列,

使用
DllImport
属性?

通常:

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

int MT123_GetVersion(IntPtr hComHandle, IntPtr pVersionBuffer, ref int len)
必须使用
Marshal.allocTaskMem
初始化
pVersionBuffer
参数。您应该使用
Marshal.Copy
将数据复制到托管阵列,然后使用
Marshal.FreeCoTaskMem
释放缓冲区

我建议您编写一个包装函数来管理细节。比如说

  • 您需要分配多少内存:这是您调用函数两次的内存,第一次传递
    null
    以检索长度的内存吗?或者它是否有一个可以硬编码的合理的最大大小
  • 返回值的含义是什么:它是一个错误代码,您应该转换为异常吗
例如:

byte[]GetVersionWrapper(IntPtr hComHandle)
{
IntPtr pVersionBuffer=IntPtr.Zero;
尝试
{
int len=0;
//首先检索长度
int status=MT123_GetVersion(hComHandle,IntPtr.Zero,ref len);
如果(状态!=0)抛出新异常(“此处消息”);
如果(len<0 | | len>1024)抛出新异常(“此处消息”);
//现在分配一个给定长度的缓冲区。
pVersionBuffer=Marshal.alloctaskmem(len);
//现在将版本信息检索到缓冲区中
int status=MT123_GetVersion(hComHandle、pVersionBuffer、ref len);
如果(状态!=0)抛出新异常(“此处消息”);
//现在将版本信息复制到托管阵列。
字节[]retVal=新字节[len];
Marshal.Copy(pVersionBuffer,retVal,0,len);
//返回托管阵列。
返回返回;
}
最后
{
//以防上面的任何内容引发异常。
FreeCoTaskMem元帅(pVersionBuffer);
}
}

有关声明的示例,请参见pinvoke:第二个参数只是byte[],没有ref。传入的len参数必须初始化为数组的长度。@HansPassant如果您这样说,我相信您是对的。我想这是引擎盖下的等效物,还是固定阵列?我对指针的理解比对P/Invoke的理解要好。pinvoke封送器负责固定作为参数传递的数组。本机代码获得指向第一个数组元素的指针。谢谢大家的评论。我已经用C#中的非托管dll测试了代码,但它会返回-1@DuijonNabik您需要查看文档以了解如何使用该函数。我们正在猜测,因为我们以前没有见过这个函数。
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);
    }
}