在 C# 中编组 char**
我正在与采用 char**
(即指向字符串的指针)的代码进行交互:
int DoSomething(Whatever* handle, char** error);
基本上,它需要一个状态句柄,如果出现问题,它会返回一个错误代码以及可选的错误消息(内存是在外部分配的,并通过第二个函数释放。我已经弄清楚了这部分:))。
但是,我不确定如何在 C# 中处理。我目前拥有的:
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
private static unsafe extern int DoSomething(IntPtr handle, byte** error);
public static unsafe int DoSomething(IntPtr handle, out string error) {
byte* buff;
int ret = DoSomething(handle, &buff);
if(buff != 0) {
// ???
} else {
error = "";
}
return ret;
}
我已经研究过,但我不知道如何将其转换为 byte[]
,适合提供给 UTF8Encoding.UTF8.GetString()< /code>
我走在正确的道路上吗?
编辑:为了更明确,库函数分配内存,必须通过调用另一个库函数来释放内存。如果解决方案没有给我留下可以释放的指针,则该解决方案是不可接受的。
额外问题:如上所述,该库使用 UTF-8 作为其字符串。我是否需要在 P/Invoke 中执行任何特殊操作,或者仅使用 string
作为普通 const char*
参数?
I am interfacing with code that takes a char**
(that is, a pointer to a string):
int DoSomething(Whatever* handle, char** error);
Basically, it takes a handle to its state, and if something goes wrong, it returns an error code and optionally an error message (the memory is allocated externally and freed with a second function. That part I've figued out :) ).
I, however, am unsure how to handle in in C#. What I have currently:
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
private static unsafe extern int DoSomething(IntPtr handle, byte** error);
public static unsafe int DoSomething(IntPtr handle, out string error) {
byte* buff;
int ret = DoSomething(handle, &buff);
if(buff != 0) {
// ???
} else {
error = "";
}
return ret;
}
I've poked around, but I can't figure out how to turn that into a byte[]
, suitable for feeding to UTF8Encoding.UTF8.GetString()
Am I on the right track?
EDIT: To make more explicit, the library function allocates memory, which must be freed by calling another library function. If a solution does not leave me with a pointer I can free, the solution is unacceptable.
Bonus question: As implied above, this library uses UTF-8 for its strings. Do I need to do anything special in my P/Invokes, or just use string
for normal const char*
parameters?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您应该能够使用引用字符串
并让运行时默认编组器为您处理此转换。您可以使用[MarshalAs(UnmanagedType.LPStr)]
提示参数上的字符宽度,以确保您使用的是 8 位字符。因为您有一个特殊的释放方法可以调用,您需要保留指针,就像您在问题示例中所示的那样。
我是这样写的:
然后你可以获得一个字符串:
并清理:
现在我们有了编组错误,所以只需返回它即可。
另请注意
MySafeHandle
类型,它将继承自System.Runtime.InteropServices.SafeHandle
。虽然不是严格需要的(您可以使用 IntPtr),但它在与本机代码互操作时为您提供更好的句柄管理。请在此处阅读:http://msdn.microsoft。 com/en-us/library/system.runtime.interopservices.safehandle.aspx。You should just be able to use aref string
and have the runtime default marshaller take care of this conversion for you. You can hint the char width on the parameter with[MarshalAs(UnmanagedType.LPStr)]
to make sure that you are using 8-bit characters.Since you have a special deallocation method to call, you'll need to keep the pointer, like you've already shown in your question's example.
Here's how I'd write it:
Then you can get a string:
And cleanup:
And now we have the marshalled error, so just return it.
Also note the
MySafeHandle
type, which would inherit fromSystem.Runtime.InteropServices.SafeHandle
. While not strictly needed (you can use IntPtr), it gives you a better handle management when interoping with native code. Read about it here: http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.safehandle.aspx.作为参考,这里是编译的代码(
但是,尚未测试,正在处理下一个测试,100%工作),它可以满足我的需要。如果有人能做得更好,那就是我所追求的:D编辑:修复了
while
循环中的逻辑,它有一个错误。For reference, here is code that compiles (
but, not tested yet, working on that nexttested, works 100%) that does what I need. If anyone can do better, that's what I'm after :DEdit: fixed the logic in the
while
loop, it had an off by one error.