今天尝试用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 时,导出函数名带@的问题的更多相关文章

  1. js里调用函数时,函数名带括号与不带括号的区别

    function test(){ return 1;}var a=test;console.log(a);//输出[Function: test]var b=test();console.log(b) ...

  2. dll 导出函数名的那些事

    dll 导出函数名的那些事 关键字: VC++  DLL  导出函数 经常使用VC6的Dependency或者是Depends工具查看DLL导出函数的名字,会发现有DLL导出函数的名字有时大不相同,导 ...

  3. DLL中导出函数的两种方式(dllexport与.def文件)

    DLL中导出函数的声明有两种方式: 一种方式是:在函数声明中加上__declspec(dllexport): 另外一种方式是:采用模块定义(.def)文件声明,(.def)文件为链接器提供了有关被链接 ...

  4. DLL声明导出函数的两种方式

    DLL中导出函数的声明有两种方式:一种为在函数声明中加上__declspec(dllexport):另外一种方式是采用模块定义(.def) 文件声明,.def文件为链接器提供了有关被链接程序的导出.属 ...

  5. (转)DLL中导出函数的两种方式(dllexport与.def文件)

    DLL中导出函数的两种方式(dllexport与.def文件)http://www.cnblogs.com/enterBeijingThreetimes/archive/2010/08/04/1792 ...

  6. 【转】DLL中导出函数的两种方式(dllexport与.def文件)

    DLL中导出函数的两种方式(dllexport与.def文件) DLL中导出函数的声明有两种方式: 一种方式是:在函数声明中加上__declspec(dllexport):另外一种方式是:采用模块定义 ...

  7. DLL的导出函数重定向机制

    曾经,调试时跟进HeapAlloc,结果发现直接进入到ntdll的RtlAllocateHeap中,感到很有趣,就使用Dependency Walker查看kernel32.dll的导出函数,结果发现 ...

  8. C++ 动态库导出函数名“乱码”及解决

    C++ 动态库导出函数名“乱码”及解决 刚接触C++,在尝试从 dll 中导出函数时,发现导出的函数名都“乱码”了. 导出过程如下: 新建一个Win32项目: 新建的解决方案里有几个导出的示例: // ...

  9. 【图文】[新手]C++ 动态库导出函数名“乱码”及解决

    刚接触C++,在尝试从 dll 中导出函数时,发现导出的函数名都"乱码"了. 导出过程如下: 新建一个Win32项目: 新建的解决方案里有几个导出的示例: // 下列 ifdef ...

随机推荐

  1. Spring Security 入门—内存用户验证

    简介 作为 Spring 全家桶组件之一,Spring Security 是一个提供安全机制的组件,它主要解决两个问题: 认证:验证用户名和密码: 授权:对于不同的 URL 权限不一样,只有当认证的用 ...

  2. Redis配置过程中的问题

    记录一下配置过程中的坑~~ 当Redis在服务器上安装完成后,get.set没有问题了,接下来在程序中使用看看... 首先 在配置文件redis.conf中,默认的bind 接口是127.0.0.1, ...

  3. ASP.NET Core中使用MialKit实现邮件发送

    # 导包 首先我们需要导入 MailKit NuGet包,NuGet安装包命令在下方拓展介绍中. # 引用命名空间 using MailKit.Net.Smtp; using MimeKit; # 邮 ...

  4. asp.net MVC中使用EasyUI Treegrid 树形网格

    引入CSS和JS <link href="~/Content/plugins/jquery-easyui-1.7.0/themes/default/easyui.css" r ...

  5. Asp.net MVC企业级开发(04)---SignalR消息推送

    Asp.net SignalR是微软为实现实时通信而开发的一个类库.可以适用于以下场景: 聊天室,如在线客服系统,IM系统等 股票价格实时更新 消息的推送服务 游戏中人物位置的实时推送 SignalR ...

  6. datatable转layui表格【偏原理】

    如题这个类负责把datatable转换为layui表格可以显示的内容.适合配合表格url字段的webapi服务端,为其返回响应字符串.代码如下:using System;using System.We ...

  7. 2019年,Golang开始吊打Java性能了!!!

    最近要同事debug性能,不经意间发现现在Golang性能开始吊打Java了!!!感觉Go发展神速!! 之前Go和Java基本是平手,甚至还有较大差距,请见https://www.cnblogs.co ...

  8. 阿里云监控RDS

    RDS性能监控API https://help.aliyun.com/document_detail/26280.html?spm=a2c4g.11186623.6.1576.341d7159uzLD ...

  9. 隐马尔科夫模型(Hidden Markov Models) 系列之三

    转自:http://blog.csdn.net/eaglex/article/details/6418219 隐马尔科夫模型(Hidden Markov Models) 定义 隐马尔科夫模型可以用一个 ...

  10. Android Okhttp POST提交键值对

    以前的项目网络连接那块一直坚持使用HttpClient,总是会出现一些莫名奇妙的问题,现在新的项目使用了OKHttp网络框架,发现超级好用,上网再了解下,发现OkHttp口碑真的不错,对比之下Http ...