将char数组从c#传递给c ++ dll

时间:2016-07-01 13:04:10

标签: c# pinvoke dllimport

我有一个LZ4 c实现的dll,我想调用

LZ4_compress_default(const char* source,char* dest,int sourceLength,int maxdestLength);

来自c#代码的功能。该函数将源数组压缩为dest数组。怎么做?

我的C#代码:

DllImport(@"CXX.dll", CharSet = CharSet.Ansi, SetLastError = true, 
    CallingConvention = CallingConvention.Cdecl)] 
internal static extern int LZ4_compress_default(
    [MarshalAs(UnmanagedType.LPArray)] char[] source, out byte[] dest, 
    int sourceSize, int maxDestSize); 


byte[] result= new byte[maxSize]; 
int x = LZ4_compress_default(array, out result, size, maxSize); 

1 个答案:

答案 0 :(得分:2)

您的代码有很多错误:

  • 设置CharSet是没有意义的,因为此处没有文字。
  • 您将SetLastError指定为true,但我怀疑您的C函数是否调用了Win32 SetLastError函数。
  • 在C#char中是一个包含UTF-16字符元素的2字节文本。这不是批量C charunsigned char,它们是8位类型。
  • 您的代码期望C函数分配托管byte[],因为字节数组被声明为out参数。您的C代码无法分配托管byte[]。相反,您需要让调用者分配数组。因此参数必须为[Out] byte[] dest

C代码应该使用unsigned char而不是char,因为您使用的是二进制而不是文本。它应该是:

int LZ4_compress_default(const unsigned char* source, unsigned char* dest,
    int sourceLength, int maxDestLength);

匹配的C#p / invoke是:

[DllImport(@"...", CallingConvention = CallingConvention.Cdecl)] 
static extern int LZ4_compress_default(
    [In] byte[] source, 
    [Out] byte[] dest, 
    int sourceLength, 
    int maxDestLength
);

这样称呼:

byte[] source = ...;
byte[] dest = new byte[maxDestLength]; 
int retval = LZ4_compress_default(source, dest, source.Length, dest.Length); 
// check retval for errors

我已经猜到函数的返回类型,因为你在C声明中省略了它,但你的C#代码表明它是int