​c++ 调用DLL函数,出现错误

Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

错误原因:

你定义函数指针原型时出错。

其实你定义的没有错,但是编译器不认识而已,因为你调用的dll函数是一个远函数,而且是一个C函数,你得告诉编译器它是个c函数才行。那么你就可以在定义该函数的时候加上一句话,

FAR PASCAL 或者 __stdcall 这个就OK了。

具体做法:

比如说你要定义一个 返回类型为空,参数为空的函数指针:

typedef void (*LPFUN)(void);

这样确实跟我们dll里的函数匹配了,上面也说了,我们应该添上几个字,告诉编译器这个是一个远的C函数。

typedef void (WINAPI *LPFUN)(void);

typedef void (__stdcall *LPFUN)(void);

typedef void    (FAR PASCAL *LPFUN)    (void);

像上面这样定义就OK了,如果用的是VC++,那么直接用第一种定义就ok了。

注意,上面是使用 MFC (DLL)的做法。

如果是WIN32 DLL,得相应的去掉WINAPI ,__stdcall ,FAR PASCAL 这几个参数。因为WIN32 DLL 默认的入栈方式为 __cedcall方式,不是__stdcall方式。

具体的组合方式太多了,反正知道错误的原因是声明相应的函数未匹配就行了。

调用DLL里的函数 或 类成员函数 碰到此错误:

Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call.  This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

函数定义的调用规则,和实际的调用规则不同。如 编译器默认的是__cdecl,而__stdcall 类型的函数却用了 __cdecl 的调用规则,由于编译时不会报错,结果出现了运行时异常。

所以把在函数定义中进行设置调用规则即可解决此问题。

如:  typedef void (__stdcall Foo)(int a);

很久没写代码,一天几行的代码:

typedef  int ( *PFUN)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
void CTestProcessMonitorDlg::OnBnClickedButton1()
{
    // TODO: Add your control notification handler code here

//MessageBox(TEXT("Hello"), TEXT("Test"));

//typedef void (*pfv) ();

HMODULE hmod = ::LoadLibraryExW(TEXT("user32.dll"), NULL, 0);
    if (hmod != NULL)
    {
        PFUN pFun= (PFUN)GetProcAddress(hmod, "MessageBoxW");
        if (pFun != NULL)
        {
            pFun(m_hWnd, TEXT("Hello"), TEXT("Test"), MB_YESNO);
        }

:FreeLibrary(hmod);
    }

}

突然出现以下的错误:

Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call.  This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

代码改为如下, 则问题没有了

typedef  int (WINAPI *PFUN)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
void CTestProcessMonitorDlg::OnBnClickedButton1()
{
    // TODO: Add your control notification handler code here

//MessageBox(TEXT("Hello"), TEXT("Test"));

//typedef void (*pfv) ();

HMODULE hmod = ::LoadLibraryExW(TEXT("user32.dll"), NULL, 0);
    if (hmod != NULL)
    {
        PFUN pFun= (PFUN)GetProcAddress(hmod, "MessageBoxW");
        if (pFun != NULL)
        {
            pFun(m_hWnd, TEXT("Hello"), TEXT("Test"), MB_YESNO);
        }

::FreeLibrary(hmod);
    }
                      
}

​c++ 调用DLL函数,出现错误的更多相关文章

  1. 在 C++Builder 工程里调用 DLL 函数

    调用 Visual C++ DLL 给 C++Builder 程序员提出了一些独特的挑战.在我们试图解决 Visual C++ 生成的 DLL 之前,回顾一下如何调用一个 C++Builder 创建的 ...

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

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

  3. 一个简洁通用的调用DLL函数的帮助类

    本次介绍一种调用dll函数的通用简洁的方法,消除了原来调用方式的重复与繁琐,使得我们调用dll函数的方式更加方便简洁.用过dll的人会发现c++中调用dll中的函数有点繁琐,调用过程是这样的:在加载d ...

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

    动态调用DLL函数有时正常,有时报Access violation的异常 typedef int (add *)(int a,int b); void test() {     hInst=LoadL ...

  5. (原创)一个简洁通用的调用DLL函数的帮助类

    本次介绍一种调用dll函数的通用简洁的方法,消除了原来调用方式的重复与繁琐,使得我们调用dll函数的方式更加方便简洁.用过dll的人会发现c++中调用dll中的函数有点繁琐,调用过程是这样的:在加载d ...

  6. GO语言 -- 调用DLL函数,填平所有的坑,最详尽攻略

    编译dll文件(源代码c++):g++ -shared main.cpp -o test.dll set GOARCH=386 第一个DLL函数,第一个参数,要求传入一个指针,直接指向[]byte类型 ...

  7. 动态加载DLL函数GetProcAddress错误

    GetLastError获取错误代码127,指代“找不到指定程序”. 解决: 转自:http://hi.baidu.com/violetwangy/item/c35b3b95ecf5374cf0421 ...

  8. C#中通过调用Dll函数时,执行一段时间后,就会报内存可能被破坏的错的解决办法

    遇到同样的问题,已经解决的:http://blog.csdn.net/youxiazzz12/article/details/24313347

  9. DLL模块例2:使用__declspec(dllexport)导出函数,extern "C"规范修饰名称,隐式连接调用dll中函数

    以下内容,我看了多篇文章,整合在一起,写的一个例子,关于dll工程的创建,请参考博客里另一篇文章:http://www.cnblogs.com/pingge/articles/3153571.html ...

随机推荐

  1. Debug, Release区别

    Debug, Release区别 Debug附加了很多调试信息,主要用于调试,所以文件大 Release就是经过优化的版本,去除了调试信息,进行了代码优化,所以文件较小,同时速度要快于Debug De ...

  2. javascript实现小九九乘法口诀

    <!DOCTYPE html> <head> <meta http-equiv="Content-Type" content="text/h ...

  3. 使用CocoaPods找不到头文件解决方法

    Project->Info->Configurations

  4. 探求C#.Net中ArrayList与Array的区别 【转】

    ArrayList与Array的区别概述     ArrayList 是数组的复杂版本.ArrayList 类提供在大多数 Collections 类中提供但不在 Array 类中提供的一些功能.例如 ...

  5. ie8不兼容input的placeholder属性但是要实现其效果的方法

    通过学习前辈的思想,个人想法整理如下: 通过两个元素标签,仿造出placeholder的内容 使用position定位好两个元素标签 第一要隐藏两个元素标签display:none,在<!--[ ...

  6. javascript高级程序设计一(80-116)

    81.函数内部属性:arguments.arguments.callee.this. window.color = "red"; var o={color:"blue&q ...

  7. viewPager使用时加载数据时显示IllegalStateException异常,解决不了。。。。

    从newsPager中得到newsDetailTitles标题的详细内容,这是通过构造器传过来的.打印日志78行能打印,45行打印出来共size是12.但是程序出现了异常java.lang.Illeg ...

  8. Java 获取 文件md5校验码

    讯雷下载的核心思想是校验文件的md5值,两个文件若md5相同则为同一文件. 当得到用户下载某个文件的请求后它根据数据库中保留的文件md5比对出拥有此文件的url, 将用户请求挂接到此url上并仿造一个 ...

  9. java -Xms -Xmx -XX:PermSize -XX:MaxPermSize

    java  -Xms -Xmx -XX:PermSize -XX:MaxPermSize     在做java开发时尤其是大型软件开发时经常会遇到内存溢出的问题,比如说OutOfMemoryError ...

  10. LintCode (9)Fizz Buzz

    下面是AC代码,C++风格: class Solution { public: vector<string> fizzBuzz(int N) { vector<string> ...