PInvoke problem

本文关键字:problem PInvoke | 更新日期: 2023-09-27 17:59:27

这是本机c方法的签名:

bool nativeMethod1
(unsigned char *arrayIn,
unsigned int arrayInSize,
unsigned char *arrayOut,
unsigned int *arrayOutSize);

我不知道为什么arrayOutSize是一个指向无符号int的指针,而不是int本身。

这就是我从C#调用它的方式:

byte[] arrayIn= Encoding.UTF8.GetBytes(source);
uint arrayInSize = (uint)arrayIn.Length;
byte[] arrayOut = new byte[100];
uint[] arrayOutSize = new uint[1];
arrayOutSize[0] = (uint)arrayOut.Length;
fixed (byte* ptrIn = arrayIn, ptrOut = arrayOut)
{
    if (nativeMethod1(ptrIn, arrayInSize, ptrOut, arrayOutSize))
    {
        Console.WriteLine("True");
    }
    else
    {
        Console.WriteLine("False");
    }
}

和一些CCD_ 1码

[DllImport(@"IcaCert.dll", EntryPoint = "CreateCert2", CallingConvention = CallingConvention.Cdecl)]<br>
public unsafe static extern bool CreateCert2WithArrays(
        byte* data, uint dataSize,<br>
        byte* result, uint[] resultSize);

根据文档,本机方法应该返回arrayOut,其值取决于arrayIn。如果其大小小于所需大小,则返回false。反之亦然。我估计arrayOut中需要850个元素。所以,当我创建新的byte[100]数组时,函数应该返回false,但它总是返回true。为什么?

PInvoke problem

您不需要不安全的代码并在此处修复。标准P/InvokeMarshaller可以胜任以下任务:

[DllImport(@"IcaCert.dll", EntryPoint = "CreateCert2", CallingConvention = CallingConvention.Cdecl)]
public static extern bool CreateCert2WithArrays(
    byte[] arrayIn, 
    uint arrayInSize,
    byte[] arrayOut,
    ref uint arrayOutSize
);
byte[] arrayIn = Encoding.UTF8.GetBytes(source);
uint arrayInSize = (uint)arrayIn.Length;
uint arrayOutSize = 0;
CreateCert2WithArrays(arrayIn, arrayInSize, null, ref arrayOutSize);
byte[] arrayOut = new byte[arrayOutSize];
CreateCert2WithArrays(arrayIn, arrayInSize, arrayOut, ref arrayOutSize);

我不确定函数的协议是什么,但如果输出数组的大小为0,则此类函数能够接收NULL是正常的。

我不认为数组是您想要的。它是指向数组大小的指针,而不是指向大小数组的指针。试试这个:

[DllImport(@"IcaCert.dll", EntryPoint = "CreateCert2", CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern bool CreateCert2WithArrays(
byte* data, uint dataSize,
byte* result, ref uint resultSize);
byte[] arrayIn= Encoding.UTF8.GetBytes(source);
uint arrayInSize = (uint)arrayIn.Length;
byte[] arrayOut = new byte[100];
uint arrayOutSize = (uint)arrayOut.Length; 
CreateCert2WithArrays (arrayIn, (uint) arrayIn.Length, arrayOut, ref arrayOutSize);
uint[] arrayOutSize = new uint[1];
arrayOut = new byte[(int)arrayOut];
CreateCert2WithArrays (arrayIn, (uint) arrayIn.Length, arrayOut, ref arrayOutSize);