MinGW 使用和创建 DLL 应注意的问题
MinGW 是 GCC 的 Windows 版本,稳定版已经到了 4.5.2,功能和性能上很好,感觉不比 Microsoft 自家的 VC 差啊。但是 MinGW 下使用和创建 DLL 倒是要特别注意,问题主要集中在 g++ 编译器(C++ 的 GNU 版本编译器)对于 DLL 的函数输入以及输出的名称修饰、调用协议上和 VC 编译器是有很大区别的。
1、MinGW 如何使用一个标准的 DLL。这里标准 DLL 指的是采用 __stdcall 调用协议、并且导出函数名称干干净净,没有函数名尾部的 @nn、没有函数名头部的下划线的。MinGW 的 g++ 程序中,对于需要从 DLL 中导入的函数,声明时必须要用 extern "C",但不要用 __declspec(dllimport),虽然 g++ 支持,但是一旦你使用,则 g++ 在链接时会自动强制在需要导入的函数名前加 _imp__ 前缀,导致链接时找不到函数名错误。所以,我们其实完全不需要用 __declspec(dllimport)。另一方面,gcc/g++ 编译器遇到代码中 __stdcall 修饰的函数名,会自动将其函数名在链接时设置为函数名@nn,nn 是函数参数栈字节数。另外,gcc/g++ 编译器/链接器在链接时其实不需要 DLL 的导入库(import lib),因为它们可以直接从 DLL 链接,这样更加方便,省去了很多从 DLL 如何生成符合格式要求的 .a 导入库等问题。只需要在 gcc/g++ 参数中加入 -Wl,--enable-stdcall-fixup -L../../Bin/ -lDLL文件名(不含.dll)即可直接从 DLL 文件本身完成链接。这里要注意,-Wl参数指示 g++ 链接器需要采用后面的链接控制参数(以逗号分隔),--enable-stdcall-fixup 告诉 g++ 链接器需要导入的 DLL 函数的名字需要自动在尾部加上 @nn 格式的后缀,以便符合 gcc/g++ 对 __stdcall 函数名的扩展规范。-L 指定 DLL 文件所在目录,-l 指定 DLL 文件名称,不带 .dll。如果不加 --enable-stdcall-fixup,gcc/g++ 总是会报链接错误,因为 gcc/g++ 将代码中需要从 DLL 导入的函数名后面都强制加了 @nn,但是 DLL 中的函数名不带 @nn,没有 --enable-stdcall-fixup,很有可能就会出错。即时不出错,也会有很多警告,很有可能会导致程序 crash!注,在 NetBeans CDT 中,-Wl,--enable-stdcall-fixup -L -l 这样的参数在链接器参数设置中指定。
2、MinGW 如何创建一个标准的 DLL。MinGW 中创建标准 DLL,应该使用 __declspec(dllexport),包括 extern "C" 等都是和 VC 一样的。但要注意,这样编译链接生成的 DLL,导出的函数名尾部都带有 @nn,为了要去除它们,必须在链接器参数设置中使用 -Wl,--kill-at,它告诉链接器创建 DLL 时导出的函数名尾部不要带有 @nn。注,在 NetBeans CDT 中,上面这个参数同样是在链接器参数设置中指定。
综上,如果创建一个 DLL,同时这个 DLL 又需要导入其他 DLL 的函数,参数就可以统一为 -Wl,--kill-at,--enable-stdcall-fixup -L -l 这样了,很方便。感觉 MinGW 确实相当强悍,跨平台,可调性很灵活,性能也很强劲,更难能可贵的是,它是一个免费而又强大的编译器!当然,搭配 NetBeans CDT 更是相当好的一款 C/C++ 开发利器。
MinGW 使用和创建 DLL 应注意的问题的更多相关文章
- MinGW g++.exe 编译 DLL 时,导出函数名带@的问题
今天尝试用CodeBlocks写了一个简单的Dll,发现生成的 dll 文件导出的函数名后面都有一个 @xxx 从生成的 libDll2.def 中看到: EXPORTS DllMain@ @ Max ...
- VC++2008 用空工程创建 DLL
VC++2008 用空工程创建 DLL 一.创建 DLL 工程项目: 1)点击菜单[File] -> [New] -> [Project...] 弹出 “New Project” 对话框: ...
- 利用openssl管理证书及SSL编程第3部分:将MinGW编译的openssl dll导出def和lib供MSVC使用
将MinGW编译的openssl dll导出def和lib供MSVC使用 前面我们用mingw把openssl 编译成了动态库,得到下面2个dll文件: libeay32.dll ssleay32.d ...
- C#创建dll类库
类库让我们的代码可复用,我们只需要在类库中声明变量一次,就能在接下来的过程中无数次地使用,而无需在每次使用前都要声明它.这样一来,就节省了我们的内存空间.而想要在类库添加什么类,还需取决于类库要实现哪 ...
- 创建dll教程
先看我的总结: 总结: 1.头文件中如果想以C形式提供,要判断,如果定义了 _cplusplus, extern "c"{ 这里写接口声明 } 2.接口声明中,要表明接口接入点的 ...
- 在VS2015中用C++创建DLL并用C#调用且同时实现对DLL的调试
from:http://m.blog.csdn.net/article/details?id=51075023 在VS2015中先创建C#项目,然后再创建要编写的动态库DLL项目,这样做的好处是整个解 ...
- MinGW gcc 生成动态链接库 dll 的一些问题汇总 (补充)
我以前写过一个小短文,介绍MinGW gcc 生成动态链接库 dll 的一些问题.当时写的并不全面.近期又遇到写新的问题.这里记录一下,做个补充. 通常情况下,dll 中的函数假设採用 _stdcal ...
- windows编程:创建DLL
创建DLL Dll是动态链接库的缩写,可以作为附加代码动态映射到进程的地址空间中. 动态库的一般创建方法如下 方法1.使用 __declspec(dllexport) 方式导出 一般的框架如下 // ...
- VS2010环境下用ANSI C创建DLL和使用方法(转)
源:VS2010环境下用ANSI C创建DLL和使用方法 . 创建DLL工程 1.2 创建一个dll工程. 操作:a.文件->新建->项目->Win32控制台应用程序. b.输入工程 ...
随机推荐
- poj3525 Most Distant Point from the Sea
题目描述: vjudge POJ 题解: 二分答案+半平面交. 半径范围在0到5000之间二分,每次取$mid$然后平移所有直线,判断半平面交面积是否为零. 我的eps值取的是$10^{-12}$,3 ...
- 【线性基】bzoj2322: [BeiJing2011]梦想封印
线性基的思维题+图常见套路 Description 渐渐地,Magic Land上的人们对那座岛屿上的各种现象有了深入的了解. 为了分析一种奇特的称为梦想封印(Fantasy Seal)的特技,需要引 ...
- MySQL中一条SQL的加锁分析
MySQL中一条SQL的加锁分析 id主键 + RC id唯一索引 + RC id非唯一索引 + RC id无索引 + RC id主键 + RR id唯一索引 + RR id非唯一索引 + RR id ...
- guava笔记
guava是在原先google-collection 的基础上发展过来的,是一个比较优秀的外部开源包,最近项目中使用的比较多,列举一些点.刚刚接触就被guava吸引了... 这个是gua ...
- 批量保存云盘链接的demo
写在前面的声明: 作为一个正在自学爬虫的小白,用爬虫爬了八千本书的云盘链接,然后就想把这写链接的资源都转存到自己的云盘里,以防某一天资源失效.本来想在网上找个能够批量保存的软件,哪知道找到几个都不能用 ...
- perl-basic-数据类型&引用
我觉得这一系列的标题应该是:PERL,从入门到放弃 USE IT OR U WILL LOSE IT 参考资料: https://qntm.org/files/perl/perl.html 在线per ...
- init_bootmem_node
初始化pg_data_t->bdtat结构体, /* * node_bootmem_map is a map pointer - the bits represent all physical ...
- TypeError: cannot use a string pattern on a bytes-like object
一劳永逸解决:TypeError: cannot use a string pattern on a bytes-like object TypeError: cannot use a string ...
- Docker初认识(一)
1)简介 1.1)什么是Docker Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的 ...
- 在win2003下apache2.2无法加载php5apache2_4.dll
昨天在一台win2003的服务器上配置apache和PHP, 我在apache的配置文件httpd.conf里添加 LoadModule php5_module "D:/php-5.4.23 ...