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

一、问题

最近做项目的时候,在调用 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);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/544630.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ai逻辑回归_人工智能中的逻辑是什么?

ai逻辑回归人工智能逻辑 (Logic in Artificial Intelligence) Logic, as per the definition of the Oxford dictionary, is "the reasoning conducted or assessed according to strict principles and validity". In Artificial Intelligence also, it carries som…

FFmpeg - 音频解码过程

1. 注册所有解码器 av_register_all(); 2. Codec & CodecContext AVCodec* codec avcodec_find_decoder(CODEC_ID_AAC); if (!codec) { fprintf(stderr, "codec not found\n"); exit(1); } AVCodecContext *codec_ctx avcodec_alloc_con…

php数据类型_PHP数据类型能力问题和解答

php数据类型This section contains Aptitude Questions and Answers on PHP Data Types. 本节包含有关PHP数据类型的 Aptitude问题和解答。 1) There are the following statements that are given below, which of them are correct about data types in PHP? In PHP, varia…

WPF 使用NotifyIcon控件

转载自&#xff1a;https://www.cnblogs.com/celery94/archive/2010/10/26/1861371.html 1.在什么地方找到NotifyIcon 普通的WPF控件基本上都是在该命名空间下&#xff1a;System.Windows.Controls&#xff0c;该命名空间在C:\Program Files\Reference Assemblies\Microsoft\…

SpringBoot 中 4 大核心组件,你了解多少?

Spring Boot 中的 4 大组件分别是&#xff1a;Spring Boot Starter、Spring Boot Autoconfigure、Spring Boot CLI 以及 Spring Boot actuator&#xff0c;接下来&#xff0c;我们分别来看他们的使用和作用。1.Spring Boot Starter1.1 Starter的应用示例<dependency><…

cache命令小结

鉴于健忘症&#xff0c;将常用的cache操作记录下来&#xff0c;便于查询&#xff1a;1、ttcurl -X PUT http://192.168.1.102:14010/dlytest -d "dlytest"curl -X DELETE http://192.168.1.105:15002/2156F298FDD458C321A30B7D26F98E6D 2、memcacheset 命令用于向缓存…

Python operator.truth()函数与示例

operator.truth()函数 (operator.truth() Function) operator.truth() function is a library function of operator module, it is used to check whether the given value is a true/truthy value or not, it returns True if the given value is a true/truthy value, False…

WPF 代码设置NotifyIcon图标

以前做Winform窗口的时候&#xff0c;设置图标非常简便&#xff0c;用WPF还是有区别的。 notifyIcon1.Icon new Icon(System.Windows.Application.GetResourceStream(new Uri("Images/Icon/Moana.ico", UriKind.Relative)).Stream);

双重检查锁,原来是这样演变来的,你了解吗

最近在看Nacos的源代码时&#xff0c;发现多处都使用了“双重检查锁”的机制&#xff0c;算是非常好的实践案例。这篇文章就着案例来分析一下双重检查锁的使用以及优势所在&#xff0c;目的就是让你的代码格调更加高一个层次。同时&#xff0c;基于单例模式&#xff0c;讲解一下…

Linux学习之FTP服务

环境&#xff1a;red hat6.5安装包&#xff1a;vsftp、ftp服务器主配置文件&#xff1a;/etc/vsftpd/vsftpd.conf主配置参数&#xff1a;anonymous_enableYES //&#xff08;默认&#xff09;允许匿名登录anon_upload_enableYES //允许匿名上传文件anon_mkdir_write_enableYES …

WakaTime 记录你的时间(Moana 自动同步信息客户端)

X、写在前面 代码界有一神器&#xff0c;可以记录敲代码的时间&#xff0c;项目名称&#xff0c;编译器等信息&#xff0c;可以极大的满足程序员的虚荣心&#xff0c;它就是 WakaTime 网站链接 WakaTime 可以记录敲代码时间&#xff0c;和具体编辑的文件等信息&#xff0c;并…

图解:为什么非公平锁的性能更高?

作者 | 王磊来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;在 Java 中 synchronized 和 ReentrantLock 默认使用的都是非公平锁&#xff0c;而它们采用非公平锁的原因都是一致的&#…

java timezone_Java TimeZone setDefault()方法与示例

java timezoneTimeZone类的setDefault()方法 (TimeZone Class setDefault() method) setDefault() method is available in java.util package. setDefault()方法在java.util包中可用。 setDefault() method is used to assign the default time zone which is retrieved by us…

5.2 测试计划和估算

5.2 测试计划和估算 2015-06-23 5.2.2. 测试计划活动&#xff08;K3&#xff09; 对整个系统或部分系统可能的测试计划活动包括&#xff1a; 确定测试的范围和风险&#xff0c;明确测试的目标&#xff1b;定义测试的整体方法&#xff08;测试策略&#xff09;&#xff0c;包括测…

Android 模拟器调试的缺点

1.模拟器调试速度太慢&#xff0c;不能清晰真实反映开发中的问题。 2.安卓定制化现象严重&#xff0c;模拟器达不到真机的真实水平&#xff0c;如控件样式、分辨率。 3.模拟器不能模拟所有的API&#xff0c;如Email、电话、短信、横竖屏、GPS、蓝牙、多点触控、震动、服务等基…

java timezone_Java TimeZone getDefault()方法与示例

java timezoneTimeZone类的getDefault()方法 (TimeZone Class getDefault() method) getDefault() method is available in java.util package. getDefault()方法在java.util包中可用。 getDefault() method is used to return the default time zone for this host. getDefaul…

死锁的 4 种排查工具 !

作者 | 王磊来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone死锁&#xff08;Dead Lock&#xff09;指的是两个或两个以上的运算单元&#xff08;进程、线程或协程&#xff09;&#xff0c;都在等待…

搜索百度百科官方创建入口,怎么创建更新公司的百度百科词条呢?

在百度搜索百度百科找到百度百科官方创建入口&#xff0c;可以上传并创建公司类的百度百科词条&#xff0c;创建词条后还可以再修改更新百科词条&#xff0c;最终完善好的百度百科词条将会在百度上获得大量曝光。那么百度百科可以怎么创建&#xff0c;下面洛希爱做百科网把十多…

【HM】第2课:JavaScript基础

<pre>day02第一天的内容&#xff1a;*html标签里面的表单标签*html标签里面的表格标签思维导图1、JavaScript的简介* 什么是JavaScript&#xff1a;js是一个基于对象和事件驱动的语言&#xff0c;应用客户端。**基于对象&#xff1a;在java里面如果使用对象需要创建&…

Nginx For Windows 关于 worker_connections 不生效问题

○、结论 Nginx For Windows 建议使用 http://nginx-win.ecsds.eu/ 下载 nginx 1.17.0.1 Crow 一、起因 项目中有一个 API 服务&#xff0c;对客户端通信进行支持&#xff0c;大概 1w 客户端&#xff0c;每分钟都会进行通信。 高峰期的时候服务负载较高&#xff0c;为了防…