MinGW g++.exe 编译 DLL 时,导出函数名带@的问题
今天尝试用CodeBlocks写了一个简单的Dll,发现生成的 dll 文件导出的函数名后面都有一个 @xxx
从生成的 libDll2.def 中看到:
EXPORTS
DllMain@ @
Max@ @
SomeFunction@ @
funReturnStr2@ @
funReturnStr@ @
updateInt2@ @
updateInt@ @
updateStr@ @
至于为什么导出的函数名后面会带@的解释:
_stdcall调用约定的函数会有@,后面的数字表示参数总共所占字节数,这是因为_stdcall函数需要被调用者清空堆栈,所以需要知道参数所占大小。 _cedcl调用约定的函数没有@及后面的数字,因为_cedcl调用约定的函数由调用者清空堆栈。 来源:https://bbs.csdn.net/topics/380193271
此时,如果在别的应用程序中加载这个dll,调用Max函数时,需要使用:GetProcAddress(hDll, "Max@8");
这种写法,让人感觉不太爽。
那么使用 MinGW g++.exe 如何让编译后的dll中的函数名不要带@呢?
一开始,我找到这篇介绍: https://www.cnblogs.com/lichmama/p/4126323.html (MinGW(GCC)编译DLL文件)
其中提到:
发现gcc可以在链接阶段通过指定 --kill-at 参数来消除这种情况。 d:\test>
#执行编译命令
d:\test>mingw32-gcc -c -DBUILD_DLL mydll.c
#执行链接命令,生成mydll.dll和静态库文件libmydll.a
d:\test>mingw32-gcc -shared -o mydll.dll mydll.o -Wl,--kill-at,--out-implib,libmydll.a
Creating library file: libmydll.a
根据提示,我在CodeBlocks 中进行设置:

然后编译的时候,提示:
mingw32-g++.exe -O2 -Wall -DBUILD_DLL -c D:\soft\c\Dll2\main.cpp -o obj\Release\main.o
mingw32-g++.exe -shared -Wl,--output-def=bin\Release\libDll2_test.def -Wl,--out-implib=bin\Release\libDll2_test.a -Wl,--dll obj\Release\main.o -o bin\Release\Dll2.dll -s --kill-at -luser32
mingw32-g++.exe: error: unrecognized command line option '--kill-at'
---> 无法识别的命令行选项'--kill-at'
什么情况?
我看到上面的这篇文章中使用的是:mingw32-gcc,而我现在用到的是 mingw32-g++.exe,难道是编译程序的不同造成的?
我对gcc的命令行参数本来就不了解,我就继续上网搜索...
然后找到这一篇:https://www.linuxidc.com/Linux/2015-12/126123.htm (MinGW 使用和创建 DLL 应注意的问题)
其中,我看到这么一句:
MinGW 如何创建一个标准的 DLL。MinGW 中创建标准 DLL,应该使用 __declspec(dllexport),包括 extern "C" 等都是和 VC 一样的。
但要注意,这样编译链接生成的 DLL,导出的函数名尾部都带有 @nn,为了要去除它们,必须在链接器参数设置中使用 -Wl,--kill-at,它告诉链接器创建 DLL 时导出的函数名尾部不要带有 @nn。
注,在 NetBeans CDT 中,上面这个参数同样是在链接器参数设置中指定。
然后,我就重新设置了一下CodeBlocks:

再次编译,成功。
搞了半天,我少写了 -Wl, 然后我就百度了一下 -Wl,看到解释:https://blog.csdn.net/wang_hufeng/article/details/53899120 (gcc编译选项-Wl)
-Wl 选项告诉编译器将后面的参数传递给链接器。
编译 dll 成功后,再次打开 libDll2.def 查看函数定义:
EXPORTS
DllMain = DllMain@ @
Max = Max@ @
SomeFunction = SomeFunction@ @
funReturnStr = funReturnStr@ @
funReturnStr2 = funReturnStr2@ @
updateInt = updateInt@ @
updateInt2 = updateInt2@ @
updateStr = updateStr@ @
这个时候,在另一个应用程序中,加载 Dll2.dll 后,调用 Dll2 中的函数 Max 的正确写法就变成理想中的:
GetProcAddress(hDll, "Max");
扩展资料:https://www.cnblogs.com/jiftle/p/8451336.html (DLL编写中extern “C”和__stdcall的作用)
完。
名品推荐:达尔丽 蚕美人 多俏美 美腾 岱之青 斯芭艺 康爵 绅诺 爱森狼 强人
MinGW g++.exe 编译 DLL 时,导出函数名带@的问题的更多相关文章
- js里调用函数时,函数名带括号与不带括号的区别
function test(){ return 1;}var a=test;console.log(a);//输出[Function: test]var b=test();console.log(b) ...
- dll 导出函数名的那些事
dll 导出函数名的那些事 关键字: VC++ DLL 导出函数 经常使用VC6的Dependency或者是Depends工具查看DLL导出函数的名字,会发现有DLL导出函数的名字有时大不相同,导 ...
- DLL中导出函数的两种方式(dllexport与.def文件)
DLL中导出函数的声明有两种方式: 一种方式是:在函数声明中加上__declspec(dllexport): 另外一种方式是:采用模块定义(.def)文件声明,(.def)文件为链接器提供了有关被链接 ...
- DLL声明导出函数的两种方式
DLL中导出函数的声明有两种方式:一种为在函数声明中加上__declspec(dllexport):另外一种方式是采用模块定义(.def) 文件声明,.def文件为链接器提供了有关被链接程序的导出.属 ...
- (转)DLL中导出函数的两种方式(dllexport与.def文件)
DLL中导出函数的两种方式(dllexport与.def文件)http://www.cnblogs.com/enterBeijingThreetimes/archive/2010/08/04/1792 ...
- 【转】DLL中导出函数的两种方式(dllexport与.def文件)
DLL中导出函数的两种方式(dllexport与.def文件) DLL中导出函数的声明有两种方式: 一种方式是:在函数声明中加上__declspec(dllexport):另外一种方式是:采用模块定义 ...
- DLL的导出函数重定向机制
曾经,调试时跟进HeapAlloc,结果发现直接进入到ntdll的RtlAllocateHeap中,感到很有趣,就使用Dependency Walker查看kernel32.dll的导出函数,结果发现 ...
- C++ 动态库导出函数名“乱码”及解决
C++ 动态库导出函数名“乱码”及解决 刚接触C++,在尝试从 dll 中导出函数时,发现导出的函数名都“乱码”了. 导出过程如下: 新建一个Win32项目: 新建的解决方案里有几个导出的示例: // ...
- 【图文】[新手]C++ 动态库导出函数名“乱码”及解决
刚接触C++,在尝试从 dll 中导出函数时,发现导出的函数名都"乱码"了. 导出过程如下: 新建一个Win32项目: 新建的解决方案里有几个导出的示例: // 下列 ifdef ...
随机推荐
- sql server 中取前n行字段最大值问题
例子 取前三行最大ID ID from Students)AS A 这样写得到的却是整个表的最大ID值,并不是我们需要的值 要在句中加入order by ID ID from Students ord ...
- idea2019注册码
都9012年了,怎么还能忍受用低版本的编辑器呢, IntelliJ IDEA 2019破解教程拿走不谢 下载工具 Mac版idea下载链接: 链接:https://pan.baidu.com/s/1m ...
- 使用vue导出excel文件
今天再开发中遇到一件事情,就是怎样用已有数据导出excel文件,网上有许多方法,有说用数据流的方式,https://www.cnblogs.com/yeqrblog/p/9758981.html,但是 ...
- Quality Center安装步骤
测试管理工具 u 安装条件: Quality Center:QC9中文版 数据库:Oracle10 g 操作系统:Windows XP u 安装步骤: 1. 点击setup.exe,出现如下界面,点 ...
- Python3报错:ModuleNotFoundError: No module named '_bz2'
系统信息 系统:CentOS Linux release 7.6.1810 (Core) python版本:python3.7 报错信息 from _bz2 import BZ2Compresso ...
- 一些你所不知道的VS Code插件
摘要: 你所不知道的系列. 原文:提高 JavaScript 开发效率的高级 VSCode 扩展之二! 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 作为一名业余爱好者.专业人员,甚 ...
- 影响Python行为的环境变量
目录 影响Python行为的环境变量 环境变量 1. PYTHONHOME 2. PYTHONPATH 3. PYTHONSTARTUP 4. PYTHONOPTIMIZE 5. PYTHONBREA ...
- mysql数据库之事务和隔离级别
事务和并发执行目的: 1.提高吞吐量,资源利用率 2.减少等待时间 连接管理器:接受请求/创建线程/认证用户/建立安全连接 并发控制:任何时候,只要有两个以上的用户试图读写同时一个文件/数据,都会带来 ...
- 如何使用Activator.CreateInstance创建一个列表<T>,其中T在运行时是未知的?
参考网址:https://cloud.tencent.com/developer/ask/185965 using System; using System.Collections.Generic; ...
- sudo:有效用户 ID 不是 0,sudo 属于 root 并设置了 setuid 位吗?
由于误操作导致无法使用sudo切换root用户 直接进入root用户并恢复文件权限,解决办法: chmod 4755 /usr/bin/sudo chmod 755 /usr/libexec/ses ...