企业网站的设计策划,手机可视化编程软件,石家庄在线制作网站,找做网站的朋友一、问题
最近做项目的时候#xff0c;在调用 c 写的 dll 的时候#xff0c;遇到一个程序异常#xff0c;发现捕捉不到#xff0c;异常为#xff1a;System.AccessViolationException
二、解决方案
详细内容和原理可以看下面引用的内容#xff0c;我这里使用的方法是在…一、问题
最近做项目的时候在调用 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 version1.0?
configurationstartupsupportedRuntime versionv4.0 sku.NETFramework,Versionv4.0//startupruntimelegacyCorruptedStateExceptionsPolicy enabledtrue //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);}
}