__declspec(dllexport) 与 DEF文件以及extern "c"??

sinux_1983 2008-11-26 02:55:09
__declspec(dllexport) 与 DEF文件以及extern "c"
情形如下:
在DLL中用 __declspec(dllexport)导出函数,比如导出int fun(void);,在EXE程序中通过LoadLibrary()显示调用,用GetProcAddress()函数来获取函数地址,获取失败,通过查看发现DLL中的函数名已经编译为?fun@@YAHXZ,通过测试,用?fun@@YAHXZ来调用GetProcAddress()确实能够获取fun的地址。
后来查询资料知道应该用extern "C" 来指定C链接。加了extern "C"之后,验证通过。

之后,我用DEF文件导出,直接用EXPORTS fun导出函数,并且不加extern "c" 发现在显示调用时也能通过。

但是,MSDN上有这么一句话:使用 .def 文件的主要缺点是:在 C++ 文件中导出函数时,必须将修饰名放到 .def 文件中,或者通过使用外部“C”用标准 C 链接定义导出函数,以避免编译器进行名称修饰。

但是我在用.def文件时并未使用修饰名,而是直接用的fun,而且没有指定C链接,怎么能够执行成功呢?
请高手详细解释一下:__declspec(dllexport) 与 def文件的区别,以及与extern "c" 的关系。

先此谢过!
...全文
516 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
colinyear 2011-01-25
  • 打赏
  • 举报
回复
真棒!
就呆在云上 2008-11-28
  • 打赏
  • 举报
回复
都有人讲解了
帮顶吧
星羽 2008-11-28
  • 打赏
  • 举报
回复
msdn上还有这么一句

dllexport of a C++ function will expose the function with C++ name mangling. If C++ name mangling is not desired, either use a .def file (EXPORTS keyword) or declare the function as extern "C".


就是说,你在def文件里写的函数名字就是导出的函数名字,相当于你使用了 extern c
星羽 2008-11-28
  • 打赏
  • 举报
回复 1
转:

第一、extern "C"的作用
比如一个C源程序A.c要使用C++编写的库函数,在A.c中#include "B.h",其中B.h中有要使用的函数的原形声明func。当编译链接源程序时,却发现了“链接错误,未决的外部符号...”的错误,这是什么原因呢?
原因就是,C编译器编译A.c时,将func编译为func,当链接时链接器去C++库中寻找func,但是C++的编译器在编译库时将func编译成 _func@yyy@rrr,自然链接器就找不着相应的函数的信息了,所以就会报错!有什么办法可以处理这种情况呢?——可以在编写C++库的时候,为每一个函数(或导出函数)加上extern "C",它的含义是告知C++编译器在编译这些函数的时候,以C编译器的方式处理函数名。这样生成的库中的函数名字就是func了,当C程序调用库函数,编译链接时,链接器就能找到期望的信息,则链接成功。

第二、.def文件的作用(仅与VC++编程相关)
前面提到,不同厂商开发的两个C编译器也会有一些差异,最突出的就是microsoft的C编译器,它对函数名字的处理很特别(究竟是什么样子,可以使用 Dumpbin工具查看dll的导出函数),所以要在使用他方编写的库时,程序链接能成功,有两种方法:1使用库编写者使用的C编译器(这里指 VC++),显然这种方法不合理;2库的编写者在使用VC++编写库时使用.def文件。
.def文件的作用即是,告知编译器不要以microsoft编译器的方式处理函数名,而以指定的某方式编译导出函数(比如有函数func,让编译器处理后函数名仍为func)。这样,就可以避免由于microsoft VC++编译器的独特处理方式而引起的链接错误。
lsldd 2008-11-28
  • 打赏
  • 举报
回复
在def文件中可以直接用EXPORTS fun
这样可以避免编译器对到处函数进行函数名修饰
sinux_1983 2008-11-26
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 healer_kx 的回复:]
不用了,写了def就可以了。
[/Quote]
MSDN上说:在 C++ 文件中导出函数时,必须将修饰名放到 .def 文件中
如果我的DLL中函数名是fun,在def文件中可以直接用EXPORTS fun 吗?
为什么?
MSDN上的这句话是怎么回事?
healer_kx 2008-11-26
  • 打赏
  • 举报
回复
extern C那个实际在调用约定那里会让你感到很差异的。
试验一下,就知道了。
healer_kx 2008-11-26
  • 打赏
  • 举报
回复
不用了,写了def就可以了。

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧