一、问题

最近做项目的时候,在调用 c 写的 dll 的时候,遇到一个程序异常,发现捕捉不到,异常为:System.AccessViolationException

二、解决方案

详细内容和原理可以看下面引用的内容,我这里使用的方法是在方法名上面添加属性:

[HandleProcessCorruptedStateExceptions]
public static void main(){//TODO
}
三、转载内容

引用链接地址:.NET 4.0里异常处理的新机制

.NET 4.0里异常处理的新机制
前几天,有一个朋友问我为什么在.NET里不能捕捉(catch)到一些异常了,而且在调试器里也捕捉不到。研究了一下,是.NET 4.0里新的异常处理机制捣的鬼。

在.NET 4.0之后,CLR将会区别出一些异常(都是SEH异常),将这些异常标识为破坏性异常(Corrupted State Exception)。针对这些异常,CLR的catch块不会捕捉这些异常,即使你用类似下面的代码:

try
{TestMethod();
}
catch (Exception e)
{Console.WriteLine("Catching exception: {0}", e);
}

也没有办法捕捉到这些异常。之所以要这样设计,在MSDN的文章Handling Corrupted State Exceptions里已经提到了。即,有一些支持插件的程序,例如Visual Studio或者SQL Server,它们支持调用托管代码编写成的插件,但是它们自己本身有很多代码是由非托管的C++写成的。由于插件经常会调用到非托管的API,而很多时间,这些插件的代码根本就不知道如何处理非托管的API抛出来的SEH异常。在4.0以前,因为SEH异常被转换成了跟普通.NET异常相同的异常,这样程序员只要用catch ( Exception e)的模式就可以捕捉到所有的异常。这样处理的问题是,由于SEH异常通常都不是托管代码抛出的,托管代码根本就不知道SEH异常被扔出来的原因,简单的catch ( Exception e)处理使得整个程序会处于一个非常不稳定的状态,使得前面被忽略的问题在后面以更严重的方式出现 — 例如保存被破坏的数据。这样,看起来使用catch ( Exception e)处理所有的异常的方法很简单,但实际上让程序员或者用户在问题延后发生时,分析起来需要花费更多的精力。

因此在4.0以后,大部分SEH(我怀疑是所有)异常都被标识成破坏性异常,在.NET里,默认情况下CLR不会捕捉它们,而是任由操作系统来处理—即关闭程序,并打开一个错误对话框通知用户。为了保证兼容性,在4.0以前编译的程序,例如在2.0、3.0和3.5编译的程序,依然采用的是老的策略—即.NET会同时捕捉.NET异常和SEH异常。而在4.0下面编译的程序才会使用新的策略,这也是在文章的开头,我的朋友所碰到的问题。你可以在.NET 4.0下面编译下面的程序,体验一下这个新变化:

Program.cs:

using System;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{class Program{[DllImport("Ref.dll")]private extern static void TestMethod();static void Main(string[] args){try{ TestMethod(); }catch (Exception e){Console.WriteLine("Catching exception: {0}", e);}}}
}

Ref.cpp:

#include "stdafx.h"
extern "C" __declspec(dllexport) void TestMethod()
{int *p = NULL;// 会导致.NET抛出一个AccessViolation异常*p = 10;
}

上面的代码里,Program.cs使用P/Invoke技术调用了Ref.dll文件里的TestMethod,但是TestMethod尝试给一个空指针赋值,导致一个AccessViolation异常。如果你在2.0下面编译program.cs,并执行的话,这个AccessViolation异常会被catch(Exception e)捕捉到,而如果你在4.0下面编译并执行的话,你会发现catch (Exception e)是不能捕捉到这个异常的。

然而并不是所有人都想要这个新的异常机制,如果你的程序是在4.0下面编译并运行,而你又想在.NET程序里捕捉到SEH异常的话,有两个方案可以尝试:

1、在托管程序的.config文件里,启用legacyCorruptedStateExceptionsPolicy这个属性,即简化的.config文件类似下面的文件:

App.config:

<?xml version="1.0"?>
<configuration><startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup><runtime><legacyCorruptedStateExceptionsPolicy enabled="true" /></runtime>
</configuration>

这个设置告诉CLR 4.0,整个.NET程序都要使用老的异常捕捉机制。

2、在需要捕捉破坏性异常的函数外面加一个HandleProcessCorruptedStateExceptions属性,这个属性只控制一个函数,对托管程序的其他函数没有影响,例如:
[HandleProcessCorruptedStateExceptions]
static void Main(string[] args)
{try{ TestMethod(); }catch (Exception e){Console.WriteLine("Catching exception: {0}", e);}
}

.NET 4.0 调用 C dll 触发 AccessViolationException 异常的处理方案相关推荐

  1. c#.net2005 调用evc4.0生成的dll文件

    又好久没有写博客了,这一段时间一直在做东西,碰到了一些问题并解决掉了,所以把它写出来.写程序时碰到的第一个问题就是用c#.net2005 调用evc4.0生成的dll文件. 首先,在调用自己写的dll ...

  2. VC++6.0如何创建与调用动态链接库(dll)

    VC++支持的DLL: DLL的编制与具体的编程语言及编译器无关,动态链接库随处可见,VC++支持三种DLL:非MFC动态库.MFC规则DLL和MFC扩展DLL.DLL导出函数(或变量.类)可供应用程 ...

  3. C# 调用C++ dll 返回char*调用方式(StringBuilder乱码)

    // CDLLDemo.cpp : 定义 DLL 应用程序的导出函数. // #include "stdafx.h" #include "string.h" # ...

  4. C#调用C++DLL类的方法

    C++的优势在于高效灵活,C#的优势在于简单易用,两者结合起来对项目开发来说是件好事,而且C++不容易反编译,也保障了代码的安全性,如果一些核心算法使用C#编写,那么保密就是一个问题.     C++ ...

  5. c怎么调用matlab dll,matlab和c++调用DLL方法(最新整理)

    <matlab和c++调用DLL方法(最新整理)>由会员分享,可在线阅读,更多相关<matlab和c++调用DLL方法(最新整理)(6页珍藏版)>请在人人文库网上搜索. 1.M ...

  6. C#调用C++dll

    1.添加命名空间 using System.Runtime.InteropServices; 2.dll的添加和函数的声明(注意一定要放在函数(方法)的外面) [DllImport("Use ...

  7. [.NET开发] C#编程调用Cards.dll实现图形化发牌功能示例

    本文实例讲述了C#编程调用Cards.dll实现图形化发牌功能.分享给大家供大家参考,具体如下: using System; using System.Collections.Generic; usi ...

  8. 非常好的dllimport 文章--在 C# 中通过 P/Invoke 调用Win32 DLL

    http://msdn.microsoft.com/zh-cn/library/aa686045.aspx 在 C# 中通过 P/Invoke 调用Win32 DLL 发布日期 : 1/13/2005 ...

  9. 如何在MFC客户端调用COM DLL

    也许有人会认为这是一个非常小儿科的问题.不过,我还是颇花费了一点时间和精力才搞清楚的.OK, 下面简单谈一下如何去做. 可以有很多方法生成一个COM DLL.比如,VB, VC++, DELPHI等等 ...

最新文章

  1. 初识好朋友计算机课件,初识电脑朋友.ppt
  2. 为什么放弃治疗_百度百科
  3. 产品经理不得不知的APP数据分析及报表设计基础
  4. 对QT学习之路12-14的源代码补充与修正
  5. java扫描包内所有类_第20天|Java入门有野,修饰符
  6. android listview 列加id,Android实战开发之ListView同一个item显示2列的实现方法
  7. VTK:相互作用之MouseEvents
  8. MATLAB观察日志(part1)--求极限
  9. rxjava 被观察者_RxJava:从未来到可观察
  10. ubuntu下如何查找某个文件的路径
  11. libvirt- Virsh 所有命令详单
  12. 输入学号查询课程c语言,广工c语言课程设计
  13. js代码测试。【一定要在真实工程下来测试是否好用】
  14. OpenCV blur和boxFilter (方框型滤波器)
  15. Thrift入门学习
  16. linux 赋权文件,linux文件赋权
  17. synctoy 远程同步_使用SyncToy将任何文件夹同步到Dropbox
  18. 关于多个Jenkins实例共享同一个工作目录的问题
  19. Dell E7440加装硬盘
  20. RBP as a streaming server(一)

热门文章

  1. c#随机数的产生与输出【C#】
  2. 多任务管理类 MutilTaskManager
  3. .NET APlayer播放器 demo
  4. 【HM】第2课:JavaScript基础
  5. nagios客户端nrped服务方式启动脚本
  6. Android Webservices 返回多行多列数据(Dataset)
  7. 智能情绪分析技术_石化缘推荐:炼化企业智能机器人巡检技术应用前景分析!...
  8. python需要什么包装_python学习之包装与授权
  9. Linux机器件拷贝文件
  10. python布尔测试对象_python布尔类型和逻辑运算