无法捕获通过 PInvoke 调用的 C dll 引起的异常

发布于 2024-10-17 08:55:11 字数 861 浏览 2 评论 0原文

我正在编写一个 C# .NET 3.5 程序,它使用最新的 MediaInfoLib Dll
看来它会导致某些文件出现异常。

我想捕获这些异常并确保我的程序继续运行,
但由于某种原因,我无法用简单的 try/catch 语句捕获它。

PInvoke 方法:

    [DllImport("MediaInfo.dll")]
    private static extern IntPtr MediaInfo_New();
    [DllImport("MediaInfo.dll")]
    private static extern IntPtr MediaInfo_Open(IntPtr Handle,MarshalAs(UnmanagedType.LPWStr)] string FileName);

用法:

    Handle = MediaInfo_New();
    try{
        MediaInfo_Open(Handle, FileName)
    } catch { } 

调用 MediaInfo_Open(Handle, FileName) 可能会导致异常。
我的程序没有使用 try/catch 语句捕获错误,而是退出并且“vshost32-clr2.exe”崩溃。 (它也会在发布版本时崩溃并且没有附加调试器)
在网上搜索后,我发现有人建议选中“启用非托管代码调试”,这只会导致我的程序退出而不会导致 vshost32-clr2.exe 崩溃。

知道我如何捕获异常吗?

I'm writing a C# .NET 3.5 program wich uses the latest MediaInfoLib Dll.
It seems that it causes an exception for some files.

I want to catch those exceptions and ensure my program continues running,
but for some reason I can't catch it with a simple try/catch statement.

PInvoke Methods:

    [DllImport("MediaInfo.dll")]
    private static extern IntPtr MediaInfo_New();
    [DllImport("MediaInfo.dll")]
    private static extern IntPtr MediaInfo_Open(IntPtr Handle,MarshalAs(UnmanagedType.LPWStr)] string FileName);

Usage:

    Handle = MediaInfo_New();
    try{
        MediaInfo_Open(Handle, FileName)
    } catch { } 

Calling MediaInfo_Open(Handle, FileName) might cause an exception.
Instead of catching the error with the try/catch statement, my program exits and "vshost32-clr2.exe" crashes. (It also crashes as a release build and with no debugger attached)
After searching the web, I found someone who suggested to check "Enable unmanaged code debugging", which only resulted in my program exiting without vshost32-clr2.exe crashing.

Any idea how I can catch the exception?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

攀登最高峰 2024-10-24 08:55:11

如果非托管 DLL 导致崩溃(而不仅仅是返回某种错误代码),则无法捕获它。一旦脱离了 .NET 运行时的控制,它就完全取决于非托管代码; .NET 运行时无能为力。

If the unmanaged DLL is causing the crash (rather than just returning an error code of some kind), then there's no way to catch it. Once you've gone outside of the .NET runtime's control, it's entirely up to the unmanaged code; there's nothing the .NET runtime can do.

2024-10-24 08:55:11

我也遇到过类似的问题(特别是 BSTR),但希望这会有所帮助。

当从非托管代码内部编组回字符串时,.NET 中存在一个错误(在 4.0 中已修复)。 更多解决

方法是更改​​ P/Invoke 签名以使用 IntPtr 并自行进行字符串编组。

[DllImport("MediaInfo.dll", EntryPoint = "MediaInfo_Open")]
private static extern IntPtr _MediaInfo_Open(IntPtr handle, IntPtr filename);

internal static extern IntPtr MediaInfo_Open(IntPtr handle, string filename)
{
     IntPtr stringPtr = Marshal.StringToBSTR(filename);
     return _MediaInfo_Open(handle, stringPtr);
}

I've had a similar problem (with BSTR specifically) but hopefully this will help.

There is a bug in .NET (fixed in 4.0) when internally marshalling strings back from unmanaged code. More Info

The work-around is to change your P/Invoke signature to use an IntPtr and do the string marshalling yourself.

[DllImport("MediaInfo.dll", EntryPoint = "MediaInfo_Open")]
private static extern IntPtr _MediaInfo_Open(IntPtr handle, IntPtr filename);

internal static extern IntPtr MediaInfo_Open(IntPtr handle, string filename)
{
     IntPtr stringPtr = Marshal.StringToBSTR(filename);
     return _MediaInfo_Open(handle, stringPtr);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文