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);
}
}