gpt4 book ai didi

c# - 在 C# 中编码一个 char**

转载 作者:可可西里 更新时间:2023-11-01 09:15:11 25 4
gpt4 key购买 nike

我正在与采用 char**(即指向字符串的指针)的代码进行交互:

int DoSomething(Whatever* handle, char** error);

基本上,它需要一个状态句柄,如果出现问题,它会返回错误代码和可选的错误消息(内存是在外部分配的,并通过第二个函数释放。那部分我已经弄明白了: )).

但是,我不确定如何在 C# 中处理 in。我目前拥有的:

[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()

我走在正确的轨道上吗?

编辑:更明确地说,库函数分配内存,必须通过调用另一个库函数来释放内存。如果解决方案没有给我留下可以释放的指针,则该解决方案是 Not Acceptable 。

额外的问题:正如上面所暗示的,这个库使用 UTF-8 作为它的字符串。我是否需要在我的 P/Invoke 中做任何特殊的事情,或者只是将 string 用于普通的 const char* 参数?

最佳答案

您应该能够使用 ref string 并让运行时默认编码器为您处理此转换。您可以使用 [MarshalAs(UnmanagedType.LPStr)] 提示参数的字符宽度,以确保您使用的是 8 位字符。

因为你有一个特殊的释放方法来调用,你需要保留指针,就像你已经在你的问题示例中展示的那样。

我是这样写的:

[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)] 
private static unsafe extern int DoSomething(
MySafeHandle handle, void** error); // byte** should work, too, I'm just lazy

然后可以得到一个字符串:

var errorMsg = Marshal.PtrToStringAnsi(new IntPtr(*error));

和清理:

[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)] 
private static extern int FreeMyMemory(IntPtr h);

// ...

FreeMyMemory(new IntPtr(error));

现在我们有编码错误,所以只需返回它。

return errorMsg;

另请注意 MySafeHandle 类型,它将继承自 System.Runtime.InteropServices.SafeHandle。虽然不是严格需要(您可以使用 IntPtr),但在与 native 代码互操作时,它可以为您提供更好的句柄管理。在这里阅读:http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.safehandle.aspx .

关于c# - 在 C# 中编码一个 char**,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4591461/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com