在C#中处理非托管dll的异常

9

I have the following function written in C#

public static string GetNominativeDeclension(string surnameNamePatronimic)
{
    if(surnameNamePatronimic == null) 
       throw new ArgumentNullException("surnameNamePatronimic");

IntPtr[] ptrs = null;
try
{
    ptrs = StringsToIntPtrArray(surnameNamePatronimic);

    int resultLen = MaxResultBufSize;
    int err = decGetNominativePadeg(ptrs[0], ptrs[1], ref resultLen);
    ThrowException(err);
    return IntPtrToString(ptrs, resultLen);
}
catch
{
    return surnameNamePatronimic;
}
finally
{
    FreeIntPtr(ptrs);
}

}

Function decGetNominativePadeg is in unmanaged dll


[DllImport("Padeg.dll", EntryPoint = "GetNominativePadeg")]
private static extern Int32 decGetNominativePadeg(IntPtr surnameNamePatronimic,
    IntPtr result, ref Int32 resultLength);

并且抛出异常:尝试读取或写入受保护的内存。这通常表明其他内存已经损坏
在C#代码中的catch实际上并不能捕获它。为什么?如何处理这个异常?
感谢您的帮助!


1
那么也许异常是在 finally 子句中引发的,这就是为什么它没有被捕获的原因?尝试注释掉 FreeIntPtr(ptrs); 然后看看会发生什么? - Wodzu
1
调试器显示它在decGetNominativePadeg函数中。 - StuffHappens
3个回答

10

0
如果要在函数内部接收IntPtr result参数的值,则必须将其标记为ref。
我没有看到在传递之前给ptrs[1]分配任何值。
尝试更改定义为:
[DllImport("Padeg.dll", EntryPoint = "GetNominativePadeg")]
private static extern Int32 decGetNominativePadeg(IntPtr surnameNamePatronimic,
    **ref** IntPtr result, ref Int32 resultLength);

可能的原因是它试图写入标记为“仅输入”的“result”。

它是由StringsToIntPtrArray函数分配的。 - StuffHappens
但是 decGet... 方法在此之前被调用了! - gvaish

0

你可能已经关闭了非托管代码的调试。

在项目属性的调试部分中,必须勾选“启用非托管代码调试选项”。之后,在调试过程中将显示异常信息。


可以使用 HandleProcessCorruptedStateExceptions - lindexi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接