DllImport、Char*&和 StringBuilder C/C#
我有一个问题,我尝试查看几乎所有的海报解决方案,但未能找到合适的解决方案。
问题很简单,想要在我的托管 C# 中从非托管 C 代码返回字符串。 c函数是:
extern "C" __declspec(dllexport) int process_batch (char *&result);
在C#中我导入了DLL:
[DllImport("mydll.dll")]
public static extern IntPtr process_batch(StringBuilder result);
我运行了,但是我的StringBuilder中的返回值是一个7-8个无意义的字符串! (我认为是内存地址)
我尝试在 StringBuilder 之前添加 ref ,这次我在 StringBuilder 中得到了正确的返回值,但我得到了 AccessViolationException : 尝试读取或写入受保护的内存。这通常表明其他内存已损坏。
所以我需要你的帮助来解决这个问题。
还有一件事,我在 c 中使用 malloc 将内存分配给 char* 变量。
谢谢,
I have a problem, I tried to look at almost all the poster solutions, unsuccessful to find a suitable one.
The question is easy, Want to have a return string from unmanaged C code in my managed C#.
The c function is:
extern "C" __declspec(dllexport) int process_batch (char *&result);
and in C# I imported the DLL:
[DllImport("mydll.dll")]
public static extern IntPtr process_batch(StringBuilder result);
I run, but the return value in my StringBuilder is a 7-8 character string of non-sense! (I think the memory address)
I tried adding ref before the StringBuilder, this time I get the correct return value in StringBuilder but I get AccessViolationException :
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
So I need your help to fix this.
Just one more thing, I use malloc in c for allocating the memory to the char* variable.
Thanks,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您确实想这样做,请将参数作为
ref IntPtr
传递,然后调用 Marshal.PtrToStringAnsi 或类似的。请注意,由于您在 C 中使用
malloc
分配字符串,因此 .NET 程序必须跟踪返回的指针,以便将其传回给您进行释放。否则你会出现内存泄漏。如果您要传递
ref StringBuilder
,您将无法释放 C 程序分配的内存。另外,正如有人在另一篇文章中评论的那样,您需要设置调用约定:
If you really want to do that, pass the parameter as a
ref IntPtr
, then call Marshal.PtrToStringAnsi, or similar.Note that, since you're allocating the string with
malloc
in C, the .NET program will have to keep track of the returned pointer so that it can pass it back to you to be deallocated. Otherwise you'll have a memory leak.If you were to pass a
ref StringBuilder
, you wouldn't be able to deallocate the memory that was allocated by the C program.Also, as somebody commented in another post, you need to set the calling convention:
我已经成功地使用了以下代码:
我建议通过
DllImportAttribute
对导入的方法进行更具体的声明。例如,尝试使用CharSet = CharSet.Auto
位,我知道这与您原来的问题并不完全相关,因为它使用了 Windows API,但也许它仍然有帮助。
I've been using the following code successfully:
I'd advise for a more specific declaration of the imported method via the
DllImportAttribute
. Try theCharSet = CharSet.Auto
bit for instanceI know that this is not exactly related to your original problem as this makes use of the Windows API, but maybe it is of help nonetheless.