PInvoke,来回数据传输
我正在尝试使用 P/Invoke 从 C# 调用 C++ 函数。
[DllImport(PATH)]
public static extern int PQunescapeByteaWrapper(
ref byte[] src,
ref byte[] dst);
匹配的 C++ 函数如下所示:
extern DECLSPEC int PQunescapeByteaWrapper(unsigned char* src, unsigned char* dst)
{
size_t dst_len;
dst = PQunescapeBytea(src, &dst_len);
return ((int)dst_len);
}
C# 的调用:
PQfun.PQunescapeByteaWrapper(ref EscapedMessage, ref UnescapedMessage);
调试到 C++ 我可以看到“src”已正确传输,并且还计算了“dst”,但是当我跳回 C# 时,“” dst" byte[] 数组 不保存"dst" unsigned char* 数组 值,而是 C++ P/Invoke 之前的原始值! 我怎样才能转移计算值?
问候,斯特凡
I 'm trying to use P/Invoke to call a C++ function from C#.
[DllImport(PATH)]
public static extern int PQunescapeByteaWrapper(
ref byte[] src,
ref byte[] dst);
The matching C++ function looks like the following:
extern DECLSPEC int PQunescapeByteaWrapper(unsigned char* src, unsigned char* dst)
{
size_t dst_len;
dst = PQunescapeBytea(src, &dst_len);
return ((int)dst_len);
}
And the call of the C#:
PQfun.PQunescapeByteaWrapper(ref EscapedMessage, ref UnescapedMessage);
Debugging into the C++ I can see that "src" is transferred correctly and also "dst" is computed, but when I jump back to C# the "dst" byte[] array does not hold the "dst" unsigned char* array value but the original one before the C++ P/Invoke!!
How can I manage to transfer the computed value?
Regards, Stefan
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你的C++方法签名和实现是错误的。您正在为参数分配一个新地址。您应该使用指向指针的指针,例如
顺便说一句,这里没有内存泄漏吗?您是否打算覆盖 dst 引用的现有数组中的值,或者您是否打算创建一个新数组并将其分配给 dst?
You're C++ method signature and implementation is wrong. You are assigning a new address to the parameter. You should use a pointer to a pointer e.g.
BTW, dont you have a memory leak here? did you intent to overwrite the values within the existing array referred to by dst or did you intent to create a new array and assign that to dst?
我认为您应该这样写,并在 C# 代码外部分配 dst 缓冲区。
I think you should write it like this instead and allocate the
dst
buffer outside in your C# code.据我所知,存在几个问题。
1)C#使用__stdcall调用C函数。
因此,您必须添加属性 [DllImport(PATH, CallingConvention=CallingConvention.Cdecl)] 或为 C 函数指定 __stdcall 属性。
2)如果需要传递数组,则不需要“ref”关键字。
3) 不能在 C# 中使用从 C++ 分配的数组。
您需要将其复制到托管内存(C# 数组)中。
为此,您可以执行两个函数。
一种计算新数组需要多少字符的方法。
另一种在目标数组中执行转换。
因此,您可以执行以下操作:
PerformMyConversion 不得返回新数组,它必须将转换的内容复制到输出参数中。
There are several problems as much as i can see.
1) C# uses __stdcall to call C functions.
So you must add attribute [DllImport(PATH, CallingConvention=CallingConvention.Cdecl)] or specify the __stdcall attribute to your C function.
2) If you need to pass an array, you don't need the "ref" keyword.
3) You cannot use in C# an array allocated from C++.
You need to copy it in managed memory (a C# array).
To do that you can do two functions for example.
One that counts how much characters you need for your new array.
Another one that performs the conversion in the destination array.
So you can do something like this:
PerformMyConversion must not return a new array, it must copies the content of the conversion into the output parameter.