将 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 char
或 unsigned 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
.
我有一个 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 函数确实调用了 Win32SetLastError
函数。 - 在 C# 中,
char
是一个包含 UTF-16 字符元素的 2 字节文本。这不会批处理 8 位类型的 Cchar
或unsigned 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
.