使用C / C ++ DLL SDK,如下所示:
INT CmdGetAllLog( BYTE *bStream, UINT16 *nCount, const UINT8 nblk )
但是在项目使用c#中,我这样做:
[DllImport("C:\\PrBioApi.dll", EntryPoint = "CmdGetAllLog")]
private static extern bool CmdGetAllLog(IntPtr bStream, ref UInt16 nCount, byte nblk);
我用它:
int nMallocSize = Marshal.SizeOf(new LOG_RECORD()) * stuSystem.wLogCnt + 4096;
byte[] pRecord = new byte[nMallocSize];
IntPtr p = Marshal.AllocHGlobal(Marshal.SizeOf(nMallocSize));
Marshal.Copy(pRecord, 0, p, pRecord.Length);
bGetSucc = CmdGetAllLog(p, ref nGet, nBlk++);
Marshal.FreeHGlobal(p);
但它不起作用。 有人可以帮助我吗?谢谢。
答案 0 :(得分:0)
您在托管数组和非托管指针之间复制的代码位于错误的位置。它需要在调用非托管函数之后。
但你可以让p / invoke marshaller为你做的工作:
[DllImport(@"C:\PrBioApi.dll")]
private static extern bool CmdGetAllLog(
byte[] bStream,
ref ushort nCount,
byte nblk
);
int nMallocSize = ...;
byte[] pRecord = new byte[nMallocSize];
bool bGetSucc = CmdGetAllLog(pRecord, ref nGet, nBlk++);
因为字节数组是blittable,所以编组器将在调用期间固定数组并将其移交给本机代码。
我假设其他两个参数都正确传递。由于您没有指定接口的任何更多细节,因此它们可能是错误的。我猜测nGet
用于告诉函数缓冲区有多大,并返回函数复制到它的程度。我无法在问题中看到您指定nGet
的位置。我相信你说得对。
其他一些评论:
DllImport
属性中指定调用约定。是本机代码cdecl
吗?INT
,但您已将其映射到bool
。如果协议是非零返回意味着成功,这可能是好的。但如果返回值表明超过该值,那么您显然需要使用int
。就个人而言,我倾向于使用int
并坚持原住民。