问题:生成的dll文件QT无法静态/隐式调用

分析:调用的lib库可能是msvc编译的,而我用Qt调用,Qt默认编译器是minGW,两种编译器生成的函数名不一样,所以调用的时候你要用哪个函数,编译结果肯定显示这个函数未定义!

解决1:用VS2008生成DLL文件时,采用__declspec方式导出函数,不要使用def模块文件,这时dll中的函数名称_funName@4规则命名

解决2:函数的调用约定改为__cdecl

导出函数的调用约定和使用这个函数时声明的调用约定必须一致,否则程序会崩溃。

在C和C++中默认的调用约定是__cdecl,上面函数完整的修饰就是:

void__declspec(dllexport) __cdeclfun();

但是windows系统用的回调函数一般都是_stdcall。

下面是各个调用约定详细的解释:

_stdcall

是Pascal方式清理C方式压栈,通常用于Win32 Api中,函数采用从右到左的压栈方式, 自己在退出时清空堆栈。VC将函数编译后会在函数名前面加上下划线前缀,在函数名后加上"@"和参数的字节数。

int f(void *p) -->> _f@4(在外部汇编语言里可以用这个名字引用这个函数)

__cdecl

C调用约定(即用__cdecl关键字说明)(The C default calling convention)按从右至左的顺序压参数入栈,由调用者把参数弹出栈。对于传送参数的内存栈是由调用者来维护的(正因为如此,实现可变参数vararg的函数(如printf)只能使用该调用约定)。

另外,在函数名修饰约定方面也有所不同。 _cdecl是C和C++程序的缺省调用方式。每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。函数采用从右到左的压栈方式。VC将函数编译后会在函数名前面加上下划线前缀。

_fastcall

调用的主要特点就是快,因为它是通过寄存器来传送参数的(实际上,它用ECX和EDX传送前两个双字(DWORD)或更小的参数,剩下的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的内存栈),

在函数名修饰约定方面,它和前两者均不同。__fastcall方式的函数采用寄存器传递参数,VC将函数编译后会在函数名前面加上"@"前缀,在函数名后加上"@"和参数的字节数。

thiscall

仅仅应用于“C++”成员函数。this指针存放于CX/ECX寄存器中,参数从右到左压。thiscall不是关键词,因此不能被程序员指定。

naked call

当采用1-4的调用约定时,如果必要的话,进入函数时编译器会产生代码来保存ESI,EDI,EBX,EBP寄存器,退出函数时则产生代码恢复这些寄存器的内容。

(这些代码称作 prolog and epilog code,一般,ebp,esp的保存是必须的).

但是naked call不产生这样的代码。naked call不是类型修饰符,故必须和_declspec共同使用。

  

另外,关键字 __stdcall、__cdecl和__fastcall可以直接加在要输出的函数前。它们对应的命令行参数分别为/Gz、/Gd和/Gr。缺省状态为/Gd,即__cdecl。

__cdecl是C/C++和MFC程序默认使用的调用约定,也可以在函数声明时加上__cdecl关键字来手工指定。采用__cdecl约定时,函数参数按照从右到左的顺序入栈,并且由调用函数者把参数弹出栈以清理堆栈。因此,实现可变参数的函数只能使用该调用约定。由于每一个使用__cdecl约定的函数都要包含清理堆栈的代码,所以产生的可执行文件大小会比较大。__cdecl可以写成_cdecl。 
__stdcall调用约定用于调用Win32 API函数。采用__stdcall约定时,函数参数按照从右到左的顺序入栈,被调用的函数在返回前清理传送参数的栈,函数参数个数固定。由于函数体本身知道传进来的参数个数,因此被调用的函数可以在返回前用一条ret n指令直接清理传递参数的堆栈。__stdcall可以写成_stdcall。

http://blog.csdn.net/liuguangzhou123/article/details/21803781

Qt Creator调用VS2008生成的DLL注意事项 good的更多相关文章

  1. c++调用matlab生成的Dll动态连接库

    点击打开链接http://download.csdn.net/detail/nuptboyzhb/4228429 c++调用matlab生成的Dll动态连接库 实验平台:   matlab 7.0(R ...

  2. C++调用C#生成的DLL文件的各种问题

    C++调用C#生成的DLL文件: 首先选择建立一个C#的类库,然后再按照需求编写需要的函数 之后,对于C++调用过程需要注意的几点: 1.使用#using <....some.dll>指出 ...

  3. 示例 - 如何在NodeJS中调用SS生成的DLL

    要想在NodeJS中调用SS生成的DLL, 需要借助EdgeJS. EdgeJS: http://tjanczuk.github.io/edge/ 如果你还不知道如何在SS中生成DLL, 请查看: S ...

  4. C#调用Matlab生成的Dll

    问题描述:最近开发需要调用matlab生成的DLL,在New MWNumericArray 对象的时候报错,提示未将对象引用到对象的实例. 问题分析:因为MWArray.dll是Matlab提供的DL ...

  5. #Lua:Lua调用C++生成的DLL库

    Lua调用C++生成的DLL库 本文参考了某大佬的博客,写得十分详细,推荐!!! 需求: 在之前的求解器中添加了Lua库,使得程序可以在Lua脚本中实现自定义函数功能,考虑到未来可能需要与第三方程序库 ...

  6. Qt显示调用vs中的dll

    网上看到很多文章写调用vc的dll,但我尝试了总是出问题,下面结合参考别人的文章,实现了Qt显示调用vs中c接口的dll. 具体直接上代码: vs中的代码: TMax.h: #ifdef TMAX # ...

  7. WPF开发的界面调用C++生成的dll文件

    以引用d1.dll为例. [生成d1.dll] 文件——新建——项目——Visual C++——Win32项目,选择DLL,点击Finish.在d1.cpp中添加代码 #include "s ...

  8. php调用C#生成的dll(二)

    根据上一篇博文,php调用c#生成的动态库,运行测试时报Fatal error: Class 'COM' not found in XXXXXXXXX 原因是php.ini中未开启COM组件的应用,解 ...

  9. Java採用JNI调用VC++生成的dll(Java与C++交互)

    应项目需求,须要android调用java,java再调用C++实现android一个图片匹配的功能,我们作为java组须要和C++和Android进行交互.以下是java和C++採用JNI的方式进行 ...

随机推荐

  1. oracle 全部查询和表空间,以及其关系

    select * from dba_users;   查看数据库里面全部用户,前提是你是有dba权限的帐号.如sys,system select * from all_users;     查看你能管 ...

  2. 【33.33%】【codeforces 586D】Phillip and Trains

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  3. matlab 图像分块及恢复

    1. block_divide % 返回的块向量构成的矩阵,其维度信息为 K^2 * N,每一列由块构成的列向量 function P = block_divide(I, K) r = size(I, ...

  4. [android]完美的解决方案ListView加载网络图片反弹问题

    为什么 先说为什么有照片反弹. 使用convertView对ListView的每一个item优化,item的复用能够有效减少内存的占用.使ListView滑动更为流畅. 但会带来一个问题,当最顶部的i ...

  5. WPF 使用 SharpDX 在 D3DImage 显示

    原文:WPF 使用 SharpDX 在 D3DImage 显示 版权声明:博客已迁移到 http://lindexi.gitee.io 欢迎访问.如果当前博客图片看不到,请到 http://linde ...

  6. Android 在子线程中更新UI的几种方法

    第一种: new Handler(context.getMainLooper()).post(new Runnable() { @Override public void run() { // 在这里 ...

  7. ocjp(scjp) 的官网样题收录-20130723

    官网上给的样题很少,带(*)的为正确答案. OBJECTIVE: 1.5: Given a code example, determine if a method is correctly overr ...

  8. oracle授权grant

    alter any cluster 修改任意簇的权限 alter any index 修改任意索引的权限 alter any role 修改任意角色的权限 alter any sequence 修改任 ...

  9. beego中各类数据库连接方式

    beego 框架是优秀得go REST API开发框架.下面针对beego中各类数据库连接操作做一个总结. 1. orm连接方式 beego中的orm操作支持三种数据库:mysql,sqlite3,p ...

  10. 信小程序支付(C#后台+前台)

    今天为大家带来比较简单的支付后台处理 首先下载官方的c#模板(WxPayAPI),将模板(WxPayAPI)添加到服务器上,然后在WxPayAPI项目目录中添加两个“一般处理程序” (改名为GetOp ...