c# P-Invoke:如何转换INT fun(BYTE *bStream, UINT16 *nCount, const

本文关键字:const BYTE bStream nCount fun UINT16 P-Invoke 何转换 转换 INT | 更新日期: 2023-09-27 18:14:40

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

,但它没有工作。有谁能帮我吗?谢谢。

c# P-Invoke:如何转换INT fun(BYTE *bStream, UINT16 *nCount, const

在托管数组和非托管指针之间复制的代码位于错误的位置。它需要在调用非托管函数之后。

但是您也可以让p/invoke编组器为您完成这项工作:

[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++);

由于字节数组是位元化的,因此编组程序将在调用期间锁定您的数组并将其传递给本机代码。

我假设其他两个参数被正确传递。由于您没有指定接口的更多细节,他们很可能是错的。我猜nGet是用来告诉函数缓冲区有多大,并返回函数复制到它的量。我看不出你在问题中哪里指定了nGet。我相信你是对的。

其他注释:

  1. 可能需要在DllImport属性中指定调用约定。本机代码也许是cdecl ?
  2. 返回值在本机代码中是INT,但您已将其映射为bool。如果协议规定非零返回意味着成功,那么这可能没有问题。但是,如果返回值指示的不止这些,那么显然需要使用int。就我个人而言,我倾向于使用int并忠于本机。