从C#传递char数组到C++ DLL

4

我有一个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); 

应该是无符号字符指针。你不能做哪个方面? - David Heffernan
遇到了将目标数组按引用传递的问题。压缩数组是由dll编写的。但我在C#端没有得到变化。 - Sayantan Ghosh
[输出] byte[] dest,显然你需要在调用函数之前分配“dest” - David Heffernan
[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); - Sayantan Ghosh
byte[] result = new byte[maxSize]; int x = LZ4_compress_default(array, result, size, maxSize); - Sayantan Ghosh
我正在使用上述调用。但现在我遇到了访问冲突异常。 - Sayantan Ghosh
1个回答

8

你的代码有几个错误:

  • 设置CharSet是无意义的,因为这里没有文本。
  • 你将SetLastError指定为true,但我怀疑你的C函数是否调用了Win32的SetLastError函数。
  • 在C#中,char是一个2字节的文本,包含一个UTF-16字符元素。这不符合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。

我已经发布了代码。我想知道为什么会出现访问违规异常。 - Sayantan Ghosh
因为你的代码存在我所描述的各种错误。我的最后一个要点是AV最可能的原因。我猜想你可能没有意识到 out byte[] dest[Out] byte[] dest 是完全不同的。 - David Heffernan
是的,我错过了那个。谢谢。那真是太有帮助了。非常感谢。我不熟悉C#,所以一直在面对这个问题。非常感谢。 - Sayantan Ghosh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接