C# P/Invoke:指向字符串作为错误消息的指针
我正在尝试使用 P/Invokes 将 llvmc 用作 C# 库(因为我找不到任何 .NET 绑定)。
但是,我有一个问题。 llvmc 使用 char** 进行错误传递。
一个例子是这样的:
char* error = NULL;
LLVMVerifyModule(PointerToSomeModule, LLVMAbortProcessAction, &error);
我应该怎样做才能允许在 C# 代码中使用这个函数?
编辑:我发现的示例也提到这次通话:
LLVMDisposeMessage(error);
我刚刚看到答案,认为这可能是一个重要的细节。
I am attempting to use llvmc as a C# library using P/Invokes(because I can't find any .NET bindings).
However, I've a problem. llvmc uses char** for error passing.
An example would be this:
char* error = NULL;
LLVMVerifyModule(PointerToSomeModule, LLVMAbortProcessAction, &error);
What should I do to allow this function to be used in C# code?
EDIT: The example I found also mentions this call:
LLVMDisposeMessage(error);
I just saw the answers and thought this could be an important detail.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
一个 char** 参数很麻烦,存在内存管理问题。如果将参数声明为“out string”,P/Invoke 编组器将尝试释放指针。这不太可能起作用,它需要使用 CoTaskMemAlloc() 分配字符串。
唯一的其他选项是您必须将其声明为“out IntPtr”并使用 Marshal.PtrToStringAnsi() 自行封送字符串。如果 LLVMC 实际上希望您释放指针,那么除了不可拔插的内存泄漏之外,这将起作用。调用它一百万次来验证这一点。有一些可能性它不会崩溃,因为它是一条错误消息,它可能返回一个指向字符串文字的指针。
剩下的唯一选择是用 C++/CLI 语言编写一个包装器,以便您可以释放指针。
A char** argument is troublesome, there is a memory management problem. If you declare the argument as "out string", the P/Invoke marshaller is going to try to free the pointer. That's very unlikely to work, it requires the string to be allocated with CoTaskMemAlloc().
The only other option you have to declare it as "out IntPtr" and marshal the string yourself with Marshal.PtrToStringAnsi(). That will work, beyond an unpluggable memory leak if LLVMC actually expects you to free the pointer. Call it a million times to verify that. There are a few odds that it won't blow since it is an error message, it might return a pointer to a string literal.
The only option left then is to write a wrapper in the C++/CLI language so you can free the pointer.
查看 StringBuilder 类。或者,您也可以简单地将参数声明为整数输出参数并使用 Marshal.PtrToStringAnsi。
Take a look at the StringBuilder class. Or you can also simply declare the parameter as an integer out parameter and use Marshal.PtrToStringAnsi.