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

Passing a char array from c# to c++ dll

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

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

来自 c# 代码的函数。该函数将源数组压缩到目标数组中。如何做到这一点?

我的 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); 

您的代码有多个错误:

  • 设置CharSet没有意义,因为这里没有文字
  • 您将 SetLastError 指定为 true,但我怀疑您的 C 函数确实调用了 Win32 SetLastError 函数。
  • 在 C# 中,char 是一个包含 UTF-16 字符元素的 2 字节文本。这不会批处理 8 位类型的 C charunsigned char
  • 您的代码期望 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

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