动态调用DLL函数有时正常,有时报Access violation的异常

typedef int (add *)(int a,int b);

void test()

{

    hInst=LoadLibraryA("aimdtl.dll");

   (FARPROC &)add=GetProcAddress(hInst,"add");

    add(1,2);

}

按这个代码执行,add函数有时OK,有时报Access violation的异常。看到提示,第一反应就是内存异常了,但是这是什么引起了内存异常呢?

于是想着用一个变量来接收add的返回值看看。

void test()

{

    hInst=LoadLibraryA("aimdtl.dll");

   (FARPROC &)add=GetProcAddress(hInst,"add");

   int sum=add(1,2);

}

结果,add函数执行了之后,还是有时OK,有时报Access violation的异常。这会是什么原因?于是谷歌了下,有人提到,可能要加__cdecall。于是我果断修改代码。新代码如下:

typedef int __cdecall (add *)(int a,int b);

void test()

{

    hInst=LoadLibraryA("aimdtl.dll");

   (FARPROC &)add=GetProcAddress(hInst,"add");

    add(1,2);

}

结果,add函数执行了之后,还是有时OK,有时报Access violation的异常。纠结了!为什么 !!这时,想起在C中调用DLL函数时,需要用__stdcall,那是不是这里也要?立即改之!

typedef int __stdcall (add *)(int a,int b);

void test()

{

    hInst=LoadLibraryA("aimdtl.dll");

   (FARPROC &)add=GetProcAddress(hInst,"add");

    add(1,2);

}

运行后,一切OK。问题至此已经解决。可这是为什么呢?于是回过头来看了看__stdcall和__cdecall的说法。

_stdcall:Win32 API的调用协议,由被调用的函数清理堆栈,所有参数自右至左入栈,生成的代码中函数名有一个_做前缀和一个@和参数的总字节数(十进制)作后缀。它不支持可变参数,但它产生的代码比_cdecl短,因为没有每次调用后的清理堆栈的代码。

_cdecl:C\C++的缺省调用协议,由调用者清理堆栈,这就是C\C++中可以使用可变参数的函数的原因,所有参数自右至作入栈,生成的代码中函数名有一个_做前缀.

至此算是明白过来了,一般dll中的函数都采用extern "C" __stdcall的方式引出函数接口的,在调用DLL中的函数时,如果没有加__stdcall和__cdecall是缺省调用了__cdecall,而__cdecall是要由调用者清理堆栈的,而在代码中并没有清理堆栈的操作,只是调用了函数,所以调

用函数的地址可能会跑飞。不跑飞就OK,而一旦跑飞就出现Access violation的异常。而_stdcall是由被调用的函数清理堆栈,所以调用函数的地址不会跑飞,自然也就OK了。

具体__stdcall/__cdecal/__fastcall的区别可以参见http://blog.csdn.net/limenglandon/article/details/8553201。

动态调用DLL函数有时正常,有时报Access violation的异常的更多相关文章

  1. C#程序实现动态调用DLL的研究(转)

    摘 要:在<csdn开发高手>2004年第03期中的<化功大法——将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资 ...

  2. 【VB技巧】VB静态调用与动态调用dll详解

    本文“[VB技巧]VB静态调用与动态调用dll详解”,来自:Nuclear'Atk 网络安全研究中心,本文地址:http://lcx.cc/?i=489,转载请注明作者及出处! [[请注意]]:在以下 ...

  3. C#程序实现动态调用DLL的研究[转]

    摘   要: 在< csdn 开发高手> 2004 年第 03 期中的<化功大法——将 DLL 嵌入 EXE >一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在 ...

  4. C#程序实现动态调用DLL的研究

    摘 要:在<csdn开发高手>2004年第03期中的<化功大法——将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资 ...

  5. 利用C#的反射机制动态调用DLL类库

    最近由于业务要求,需要动态调用DLL类库,所以研究了一下,感觉还好也不太难,今天就把自己理解的写了一个小例子(已经通过VS2005跑通),供大家一起研究和探讨,有理解不当的地方还请高手们多多指正,谢谢 ...

  6. VC动态调用DLL

    1. //函数指针声明 typedef int (_stdcall MYDLLFUN)(char* _pcOut, /*INOUT*/int *_piOutBufLen, char* _pcIn, i ...

  7. 如何动态调用 C 函数

    JSPatch 支持了动态调用 C 函数,无需在编译前桥接每个要调用的 C 函数,只需要在 JS 里调用前声明下这个函数,就可以直接调用: require('JPEngine').addExtensi ...

  8. C++利用模板在Windows上快速调用DLL函数

    更新日志 --------- 2021/08/01 更新V2.2 增加 GetHmodule 函数 - 允许用户获取HMODULE以验证加载DLL是否成功. 2021/08/03 更新V2.3 增加 ...

  9. 卸载AppDomain动态调用DLL异步线程执行失败

    应用场景 动态调用DLL中的类,执行类的方法实现业务插件功能 使用Assembly 来实现 但是会出现逻辑线程数异常的问题 使用AppDomain 实现动态调用,并卸载. 发现问题某个插件中开启异步线 ...

随机推荐

  1. codeforces 392B Tower of Hanoi

    把前n个碟子从第一个塔移动到第三个塔有两种方法: 1.把前n-1个移动到第二个塔,把第n个移动到第三个塔,然后把前n-1个从第二个移动到第三个: 2.把前n-1个移动到第三个塔,把第n个移动到第二个塔 ...

  2. Linux网络地址转换分析

    Linux网络地址转换分析 地址转换用来改变源/目的端口,是netfilter的一部分,也是通过hook点上注册相应的结构来工作. Nat注册的hook点和conntrack相同,只是优先级不同,数据 ...

  3. c#使用XSLT将xml文档转换为html文档

    需要引用下面的命名空间: using System.Xml; using System.Xml.Xsl; 方法实现: public static string ConvertXML(XmlDocume ...

  4. cogs_14_搭配飞行员_(二分图匹配+最大流,网络流24题#01)

    描述 http://cojs.tk/cogs/problem/problem.php?pid=14 有一些正飞行员和副飞行员,给出每个正飞行员可以和哪些副飞行员一起飞.一架飞机上必须一正一副,求最多多 ...

  5. Codevs_1403_新三国争霸_(Kruskal+动态规划)

    描述 http://codevs.cn/problem/1403/ 共t天,n个点,m条边,选择每条边要付出不同的代价,其中某些天某些边不能用,要保证每一天n个点都是连通的,如果换方案要付出额外的代价 ...

  6. BZOJ_1270_雷涛的小猫_(动态规划)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1270 有n棵树,高度为h.一只猫从任意一棵树的树顶开始,每次在同一棵树上下降1,或者跳到其他树 ...

  7. PHP 'ext/gd/gd.c' gdImageCrop整数符号错误漏洞

    漏洞版本: PHP 5.5.x 漏洞描述: CVE ID:CVE-2013-7328 PHP是一种HTML内嵌式的语言. PHP 'ext/gd/gd.c' gdImageCrop函数存在多个整数符号 ...

  8. Android 实用代码七段(三)

    前言 终于又攒了一篇出来,本系列以实用为主,欢迎和我分享和推荐好用的代码段~~ 声明 欢迎转载,但请保留文章原始出处:)  博客园:http://www.cnblogs.com 农民伯伯: http: ...

  9. 普通Java类获取spring 容器的bean的5种方法

    方法一:在初始化时保存ApplicationContext对象方法二:通过Spring提供的工具类获取ApplicationContext对象方法三:继承自抽象类ApplicationObjectSu ...

  10. 开始同时在cnblog和BAE上写博客

    研究生第一学期已过一半,开始理论学习,当然不能忘了实践学习. \[\frac{{ - b \pm \sqrt {{b^2} - 4ac} }}{{2a}}\]