动态调用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. BT5之配置笔记

    BT5本来就是用Ubuntu 10.04做得蓝本,所以,我在配置BT5的时候,基本上都是按照Ubuntu 10.04的配置方法,在配置BT5 1    系统基本设置 1.1  安装Ubuntu10.0 ...

  2. Codeforces Round #211 (Div. 2)

    难得一次比赛能够自己成功A掉四个题: A题:水题,模拟一下就行: #include <iostream> #include <cstdio> using namespace s ...

  3. PHP reset() 函数

    定义和用法 reset()函数把数组的内部指针指向第一个元素,并返回这个元素的值.若失败,则返回 FALSE. reset()函数用来将数组指针设置回数组的开始位置.如果需要在一个脚本中多次查看或处理 ...

  4. 让动画不再僵硬:Facebook Rebound Android动画库介绍

    introduction official site:http://facebook.github.io/reboundgithub : https://github.com/facebook/reb ...

  5. hadoop中的分布式缓存——DistributedCache

    分布式缓存一个最重要的应用就是在进行join操作的时候,如果一个表很大,另一个表很小很小,我们就可以将这个小表进行广播处理,即每个计算节点 上都存一份,然后进行map端的连接操作,经过我的实验验证,这 ...

  6. 如何修改word的项目编号

    在操作word文档时,有时会遇到word文档中的项目编号不是自己需要的,并造成word项目编号的混乱,如何word中的两级项目编号不统一,为解决会word的项目编号混乱问题,小编将教大家如何修改wor ...

  7. uiview scale

    http://stackoverflow.com/questions/3946797/cgaffinetransformmakescale-makes-uiview-jump-to-original- ...

  8. The Task: Events, Asynchronous Calls, Async and Await

    The Task: Events, Asynchronous Calls, Async and Await Almost any software application today will lik ...

  9. POJ 2411 Mondriaan's Dream

    思路:状态压缩dp,如果在(i,j)位置横着放砖块,那么(i,j)和(i+1.j)都是1,如果竖着放砖块,那么(i,j)为0,(i,j+1)为1,这样每行就可以用一个整数来存放状态,设dp[i][j] ...

  10. GTK+中的树状列表构件(GtkTreeView)

    GTK+中的树状列表构件(GtkTreeView) GTK+中的树状列表构件(GtkTreeView) 在本章的GTK+程序设计教程中,我们将向大家重点介绍非常常用也有点复杂的构件--GtkTreeV ...