csharp zlib zlibversion pinvoke 导致随机崩溃(堆损坏)
csharp zlib zlibversion pinvoke causes random crash (heap corruption)
我一直在调试我们的一个应用程序中的堆损坏异常。它是上个月(2015 年 3 月)在未更改的代码上才开始发生的。 windbg 将其缩小到我们使用 pinvoke 从 c# 调用 zlib 函数的一些代码。
代码片段是:
public class Info
{
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
private static extern string zlibVersion();
public static string Version { get { return zlibVersion(); } }
}
看起来这段代码来自 zlib.net source\contrib\dotzlib\DotZLib\DotZlib.cs,它是 zlib.dll.
的 dotnet 包装器
问题:知道为什么这会导致堆损坏吗? dotnet pinvoke 有问题吗?我认为许多其他应用程序可能会使用相同的包装器。但是我没有发现其他人在互联网上抱怨这个。
编辑 1 - 这是来自 zlib 源 (zlib.h) 的非托管接口:
ZEXTERN const char * ZEXPORT zlibVersion OF((void));
最可能的解释是,此函数 returned 的 C 字符串是静态分配的。因此,调用者不得解除分配,这是 p/invoke 编组器对您的代码所做的。它通过将 C 字符串传递给 CoTaskMemFree
来完成此操作。
所以你需要阻止这种情况发生。通过手动封送 return 值来做到这一点。
[DllImport("ZLIB1.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr zlibVersion();
public static string Version
{
get
{
return Marshal.PtrToStringAnsi(zlibVersion());
}
}
我一直在调试我们的一个应用程序中的堆损坏异常。它是上个月(2015 年 3 月)在未更改的代码上才开始发生的。 windbg 将其缩小到我们使用 pinvoke 从 c# 调用 zlib 函数的一些代码。
代码片段是:
public class Info
{
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
private static extern string zlibVersion();
public static string Version { get { return zlibVersion(); } }
}
看起来这段代码来自 zlib.net source\contrib\dotzlib\DotZLib\DotZlib.cs,它是 zlib.dll.
的 dotnet 包装器问题:知道为什么这会导致堆损坏吗? dotnet pinvoke 有问题吗?我认为许多其他应用程序可能会使用相同的包装器。但是我没有发现其他人在互联网上抱怨这个。
编辑 1 - 这是来自 zlib 源 (zlib.h) 的非托管接口:
ZEXTERN const char * ZEXPORT zlibVersion OF((void));
最可能的解释是,此函数 returned 的 C 字符串是静态分配的。因此,调用者不得解除分配,这是 p/invoke 编组器对您的代码所做的。它通过将 C 字符串传递给 CoTaskMemFree
来完成此操作。
所以你需要阻止这种情况发生。通过手动封送 return 值来做到这一点。
[DllImport("ZLIB1.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr zlibVersion();
public static string Version
{
get
{
return Marshal.PtrToStringAnsi(zlibVersion());
}
}