代码之家  ›  专栏  ›  技术社区  ›  xenn_33

我应该从P/Invoke不安全代码中得到什么异常?

  •  3
  • xenn_33  · 技术社区  · 16 年前

    在我的解决方案中,我写了以下内容:

    [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
    

    假设copyFileEx是以dllimport属性的setLastError=true参数导出的,我有机会在这里获得任何未更改的异常吗?

    我对runtimewrappedException实例中包装的非clr异常特别感兴趣。在C++中,“抛出1”是一个有效的构造。那么,我应该从这样的p/invoke调用中期望哪些异常,在哪里可以获得关于异常的信息(msdn没有提到copyfileex的异常)?

    1 回复  |  直到 16 年前
        1
  •  6
  •   Stephen Cleary    16 年前

    如果DLL使用Win32结构化异常处理系统,则该DLL引发的任何异常都将转换为 OutOfMemoryException , AccessViolationException , NullReferenceException (很少),或 SEHException .

    RuntimeWrappedException 仅在以下情况下使用 管理 C++抛出一个非 Exception -派生对象。它不用于非托管DLL。如果你有 管理 做了一个C++ DLL throw 1 ,然后你就可以 运行时包装例外 .

    塞希特 作为不可映射的SEH异常类型的全部捕获 非受管的 DLL。这将包括任何C++类,或者 投掷1 例子。AFAIK,没有办法将C++特定的异常信息从 塞希特 不过,如果你足够努力的话,我相信这是可以破解的。

    请注意,有一些DLL不使用Win32结构化异常处理系统。最值得注意的是Cygwin DLL。在这种情况下,任何C++异常可能会破坏进程或至少线程。当然,所有的Windows DLL(包括定义 CopyFileEx )使用Win32结构化异常处理,就像微软C++编译器创建的任何非托管DLL一样。

    还要注意,win32 API(包括 复制文件 )通常不使用Win32结构化异常报告错误;它们通过 GetLastError . 让大多数win32函数抛出win32结构化异常的唯一方法是传递极其无效的参数(例如要求它在 ntdll.dll )