非托管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
属性的?
答案 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);
}
}