在 P/Invoking 时处理调用函数的第三方库会导致堆损坏
Dealing with a 3rd party library who's function call causes heap corruptions when P/Invoking
我创建了一个调用 FlexNet Publisher 的库包装器。它是用 C 语言编写的。我正在尝试 P/Invoke 它:
[DllImport("lmgr11.dll")]
public static extern void free_job();
它的实现相当简单:
void WINAPI free_job()
{
if (jobPtr != NULL)
lc_free_job(jobPtr);
jobPtr = NULL;
}
文档说 lc_free_job
应该释放作业以及所有资源。从本机代码调用 lc_free_job
工作得很好(我让一个 ATL 对象通过一个 COM 对象向它公开了一个包装器,我可以整天从 Visual C++ 控制台应用程序使用这个方法,所以我知道它必须工作) .
但是,在 C# 中,当我尝试 P/Invoke 此方法时,出现以下错误,导致我的应用程序崩溃:
Unhandled exception at 0x00007FFA39358283 (ntdll.dll) in
CerberusTestHarness.exe: 0xC0000374: A heap has been corrupted
(parameters: 0x00007FFA393AF6B0).
这是为什么?我可以抓住它或以任何方式规避它吗?如果我将调用包装在 try-catch 中,我似乎无法捕获异常,因为它不会抛出 .NET 异常。请注意,我没有 lc_free_job
的源代码,因此很遗憾,我无法检查或查看其源代码。它是用 C 写的。
问题是由于我的 C# P/Invoke 代码来自之前的调用。希望这对遇到同样问题的其他人有所帮助。
我已经定义了这个 P/Invoke 以从 returns char *
:
的函数中获取错误字符串
[DllImport("lmgr11.dll")]
public static extern string errstring();
每当我的第 3 方库出现故障时,我都会调用它,如上所述。这不是 P/Invoke 的正确方法 returns char *
的方法。否则,当从本机端释放错误时,由于此字符串的编组方式将导致堆损坏。
需要这样定义:
[DllImport("lmgr11.dll")]
public static extern IntPtr errstring();
并调用如下:
var errorMessage = Marshal.PtrToStringAnsi(errstring());
我创建了一个调用 FlexNet Publisher 的库包装器。它是用 C 语言编写的。我正在尝试 P/Invoke 它:
[DllImport("lmgr11.dll")]
public static extern void free_job();
它的实现相当简单:
void WINAPI free_job()
{
if (jobPtr != NULL)
lc_free_job(jobPtr);
jobPtr = NULL;
}
文档说 lc_free_job
应该释放作业以及所有资源。从本机代码调用 lc_free_job
工作得很好(我让一个 ATL 对象通过一个 COM 对象向它公开了一个包装器,我可以整天从 Visual C++ 控制台应用程序使用这个方法,所以我知道它必须工作) .
但是,在 C# 中,当我尝试 P/Invoke 此方法时,出现以下错误,导致我的应用程序崩溃:
Unhandled exception at 0x00007FFA39358283 (ntdll.dll) in CerberusTestHarness.exe: 0xC0000374: A heap has been corrupted (parameters: 0x00007FFA393AF6B0).
这是为什么?我可以抓住它或以任何方式规避它吗?如果我将调用包装在 try-catch 中,我似乎无法捕获异常,因为它不会抛出 .NET 异常。请注意,我没有 lc_free_job
的源代码,因此很遗憾,我无法检查或查看其源代码。它是用 C 写的。
问题是由于我的 C# P/Invoke 代码来自之前的调用。希望这对遇到同样问题的其他人有所帮助。
我已经定义了这个 P/Invoke 以从 returns char *
:
[DllImport("lmgr11.dll")]
public static extern string errstring();
每当我的第 3 方库出现故障时,我都会调用它,如上所述。这不是 P/Invoke 的正确方法 returns char *
的方法。否则,当从本机端释放错误时,由于此字符串的编组方式将导致堆损坏。
需要这样定义:
[DllImport("lmgr11.dll")]
public static extern IntPtr errstring();
并调用如下:
var errorMessage = Marshal.PtrToStringAnsi(errstring());