[英]What exceptions should I expect from P/Invoke unsafe code?
In my solution I've written the following: 在我的解决方案中,我写了以下内容:
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern unsafe bool CopyFileEx(string lpExistingFileName,
string lpNewFileName, CopyProgressRoutine lpProgressRoutine, IntPtr lpData,
Boolean* pbCancel, CopyFileFlags dwCopyFlags);
...
bool result;
unsafe{
result = CopyFileEx(sourceFile, targetFile, null, IntPtr.Zero,
null /* pointer */, 0);
}
if(!result)
Win32Exception exc = new Win32Exception(Marshal.GetLastWin32Error());
// parameter could be omitted according to Win32Exception constructor
// implementation
In the assumption that CopyFileEx was exported with SetLastError = true parameter of DllImport attribute, do I have a chance to get any unhalted exception here? 假设CopyFileEx是使用DllImport属性的SetLastError = true参数导出的,我是否有机会在此获取任何未定型异常?
I'm specifically interested in non-CLR exceptions which are wrapped in RuntimeWrappedException instance. 我特别感兴趣的是包含在RuntimeWrappedException实例中的非CLR异常。 In C++ "throw 1" is a valid construct.
在C ++中,“throw 1”是一个有效的构造。 So what exceptions should I expect from such P/Invoke calls and where I can obtain such information regarding exceptions (MSDN says nothing regarding exceptions from CopyFileEx)?
那么我应该从这样的P / Invoke调用中获得什么异常,哪些我可以获得有关异常的信息(MSDN对CopyFileEx中的异常没有任何说明)?
If a DLL uses the Win32 structured exception handling system, then any exceptions thrown by the DLL will be translated to OutOfMemoryException
, AccessViolationException
, NullReferenceException
(rarely), or SEHException
. 如果DLL使用Win32结构化异常处理系统,则DLL抛出的任何异常都将转换为
OutOfMemoryException
, AccessViolationException
, NullReferenceException
(很少)或SEHException
。
RuntimeWrappedException
is only used when managed C++ throws a non- Exception
-derived object. 仅当托管 C ++抛出非
Exception
-derived对象时,才使用RuntimeWrappedException
。 It is not used for unmanaged DLLs. 它不用于非托管DLL。 If you had a managed C++ DLL that did a
throw 1
, then you could catch RuntimeWrappedException
. 如果你有一个托管 C ++ DLL,它执行了
throw 1
,那么你可以捕获RuntimeWrappedException
。
SEHException
acts as a catch-all for the unmappable types of SEH exceptions from unmanaged DLLs. SEHException
充当来自非托管 DLL的不可映射类型的SEH异常的全能。 This would include any C++ class, or the throw 1
example. 这将包括任何C ++类或
throw 1
示例。 AFAIK, there is no way to pull the C++-specific exception info out of SEHException
, though I'm sure it's hackable if you try hard enough. AFAIK,没有办法从
SEHException
特定于C ++的异常信息,但我确信如果你努力尝试它是可以SEHException
。
Note that there are a few DLLs that do not use the Win32 structured exception handling system. 请注意,有一些DLL不使用Win32结构化异常处理系统。 Most notably Cygwin DLLs.
最值得注意的是Cygwin DLL。 In that case, any C++ exception is likely to crash the process or at least your thread.
在这种情况下,任何C ++异常都可能导致进程或至少是您的线程崩溃。 Naturally, all the Windows DLLs (including the one defining
CopyFileEx
) do use Win32 structured exception handling, as do any unmanaged DLLs created by Microsoft's C++ compiler. 当然,所有Windows DLL(包括定义
CopyFileEx
DLL)都使用Win32结构化异常处理,就像Microsoft的C ++编译器创建的任何非托管DLL一样。
Also note that the Win32 API (including CopyFileEx
) does not normally report errors using Win32 structured exceptions; 另请注意,Win32 API(包括
CopyFileEx
)通常不会使用Win32结构化异常报告错误; they report them via GetLastError
. 他们通过
GetLastError
报告它们。 The only way to get most Win32 functions to throw a Win32 structured exception is to pass it wildly invalid arguments (such as asking it to write into the middle of ntdll.dll
). 让大多数Win32函数抛出Win32结构化异常的唯一方法是传递它非常无效的参数(例如要求它写入
ntdll.dll
的中间)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.