我有一个调用外部函数的C#程序。C函数如下:
char *confd_ns2prefix(u_int32_t ns)
{
struct schema *schema = find_schema(ns);
if (schema != NULL)
return (char *)schema->prefix;
return NULL;
}[DllImport("libconfd.so", SetLastError = true)]
public static extern string confd_ns2prefix(UInt32 ns);Console.WriteLine(libconfd.confd_ns2prefix((uint)1826703833));
Console.WriteLine(libconfd.confd_ns2prefix((uint)1826703833));第二次我会得到一个双倍的自由错误:
ncm
dotnet(39827,0x11dd24dc0) malloc:双重释放对象0x7f8182037b20
dotnet(39827,0x11dd24dc0) malloc:*在malloc_error_break中设置断点以进行调试
看起来编组器试图释放对象两次,但我不知道为什么...事实上,它甚至不应该释放它。
有什么想法吗?
发布于 2020-04-09 21:48:40
实际上所有内容都在这里进行了解释:https://docs.microsoft.com/en-us/dotnet/framework/interop/default-marshaling-behavior
但是,如果将该方法定义为平台调用原型,将每个BSTR类型替换为字符串类型,并调用MethodOne,则公共语言运行库将尝试释放b两次。您可以通过使用IntPtr类型而不是字符串类型来更改封送处理行为。
运行库始终使用CoTaskMemFree方法来释放内存。如果您正在使用的内存不是使用CoTaskMemAlloc方法分配的,则必须使用IntPtr并使用适当的方法手动释放内存。
我修复如下
[DllImport("libconfd.so", SetLastError = true)]
public static extern IntPtr confd_ns2prefix(UInt32 ns);
public static string confd_ns2prefix_w(UInt32 ns) {
return Marshal.PtrToStringAnsi(confd_ns2prefix(ns));
}https://stackoverflow.com/questions/61122557
复制相似问题