extern "C" 和 DEF 文件.
参考:
http://www.cnblogs.com/whiteyun/archive/2011/07/22/2113560.html
问题: 如果用了 DEF 文件来导出 DLL 的函数, 还需要在导出的函数声明前面加 extern "C" 吗?
DEMO 下载: http://pan.baidu.com/s/1kTTY6rH
extern "C" 的目的是告诉 C++ 编译器不要对函数名进行改名处理(以便支持函数重载), 而是按照 C 编译器的方式, 不对函数名进行修改.
如果专门有头文件声明函数的话, extern "C" 以及 __declspec(dllexport) 只需要出现在头文件中即可, 定义函数的 .cpp 文件中可有可无.
如果没专门有头文件声明函数的话, extern "C" 以及 __declspec(dllexport) 必须出现在定义函数的 .cpp 文件中.
上述规则对纯 C 项目中的 __declspec(dllexport) 也适用.
做的实验, 思路如下, 即看各种配置下 Hello.h 中需不需要加 extern "C" 从而 UI2.EXE 可以通过 GetProcAddress("fnHello") 找到 Hello.dll 中的 fnHello:
注: Hello 项目中有一个 Hello.h
UI2.EXE 编译为 C++ 项目 , HELLO.DLL 编译为 C++ 项目, C++ 编译器版本相同, Hello.h 中, 用 __declspec(dllexport) :
Hello.h 有 extern "C", 成功, dumpbin /exports hello.dll 得到 _fnHello
Hello.h 无 extern "C", 失败, dumpbin /exports hello.dll 得到 ?fnHello@@YAXXZ
UI2.EXE 编译为 C++ 项目 , HELLO.DLL 编译为 C++ 项目, C++ 编译器版本相同, Hello.h 中, 无 __declspec(dllexport), 用 DEF 文件:
Hello.h 有 extern "C", 成功, dumpbin /exports hello.dll 得到 _fnHello
Hello.h 无 extern "C", 成功, dumpbin /exports hello.dll 得到 ?fnHello@@YAXXZ
UI2.EXE 编译为 C++ 项目 , HELLO.DLL 编译为 C 项目, Hello.h 中, 用 __declspec(dllexport):
Hello.h 有 extern "C", 成功, dumpbin /exports hello.dll 得到 _fnHello
Hello.h 无 extern "C", 成功, dumpbin /exports hello.dll 得到 _fnHello
UI2.EXE 编译为 C++ 项目 , HELLO.DLL 编译为 C 项目, Hello.h 中, 无 __declspec(dllexport), 用 DEF 文件:
Hello.h 有 extern "C", 成功, dumpbin /exports hello.dll 得到 _fnHello
Hello.h 无 extern "C", 成功, dumpbin /exports hello.dll 得到 _fnHello
UI2.EXE 编译为 C 项目 , HELLO.DLL 编译为 C++ 项目, Hello.h 中, 用 __declspec(dllexport):
Hello.h 有 extern "C", 成功, dumpbin /exports hello.dll 得到 _fnHello
Hello.h 无 extern "C", 失败, dumpbin /exports hello.dll 得到 ?fnHello@@YAXXZ
UI2.EXE 编译为 C 项目 , HELLO.DLL 编译为 C++ 项目, Hello.h 中, 无 __declspec(dllexport), 用 DEF 文件:
Hello.h 有 extern "C", 成功, dumpbin /exports hello.dll 得到 _fnHello
Hello.h 无 extern "C", 成功, dumpbin /exports hello.dll 得到 ?fnHello@@YAXXZ
总结:
当 DLL 是 C++ 实现的时候,
用 DEF 文件, 无 extern "C", 此时 DLL 中导出的函数名仍然会被 C++ 编译器修改, 但仍然可用 GetProcAddress 找到函数.
用 __declspec(dllexport), 如果没有 extern "C", GetProcAddress 找不到函数.
当 DLL 是 C 实现的时候,
因为用的 C 编译器, 所以无论用 DEF 文件还是 __declspec(dllexport), 都不需要 extern "C", DLL 中导出的函数名始终不会被修改.
GetProcAddress 始终能找到函数.
extern "C" 和 DEF 文件.的更多相关文章
- windows dll的def文件
DLL(testcase_1.dll )源码:myfun.h #pragma once #ifdef TESTCASE_1_EXPORTS #define MY_API __declspec(dlle ...
- 简单了解 DLL中, .def 文件及C#调用C++方法
DLL中导出函数的声明有两种方式: 1.在函数声明中加上__declspec(dllexport) //以下内容为 .h 文件中的内容 //向外界提供的端口 extern"C" _ ...
- DLL中导出函数的两种方式(dllexport与.def文件)
DLL中导出函数的声明有两种方式: 一种方式是:在函数声明中加上__declspec(dllexport): 另外一种方式是:采用模块定义(.def)文件声明,(.def)文件为链接器提供了有关被链接 ...
- (转)DLL中导出函数的两种方式(dllexport与.def文件)
DLL中导出函数的两种方式(dllexport与.def文件)http://www.cnblogs.com/enterBeijingThreetimes/archive/2010/08/04/1792 ...
- DLL DEF文件编写方法 VC++ 调用、调试DLL的方法 显式(静态)调用、隐式(动态)调用
DLL 文件编写方法: 1.建立DLL工程 2.声明.定义要导出的函数 BOOL WINAPI InitDlg( HWND hTabctrl,TShareMem* pTshare,CRect* prc ...
- 使用def文件简化dll导出
原文链接地址:http://www.cnblogs.com/TianFang/archive/2013/05/04/3059073.html 在C++中,我们可以通过 __declspec(dllex ...
- 【转】DLL中导出函数的两种方式(dllexport与.def文件)
DLL中导出函数的两种方式(dllexport与.def文件) DLL中导出函数的声明有两种方式: 一种方式是:在函数声明中加上__declspec(dllexport):另外一种方式是:采用模块定义 ...
- VC2010 利用 def 文件生成 dll 文件的方法
近期有个需求,要生成一个dll 文件.文件里的函数都是採用 stdcall 函数调用约定,可是不希望函数名被修饰(add 被修饰成 add@8). 这时就要用def 文件了. 比方我有以下两个函数: ...
- 通过dll或def文件提取lib导入库文件
很多时候第三方库或其他项目提供的库多数会以动态库的形式提供dll以及相应的lib导入库.头文件,不过也有的只是提供dll和头文件,或者也提供了def模块定义(用于导出函数)文件,此时若使用将不得不调用 ...
随机推荐
- JavaScript系列:event.bubbles属性(并不是所有的事件都具有冒泡)
地址 https://www.w3.org/TR/DOM-Level-3-Events/#h3_interface-Event https://segmentfault.com/q/101000000 ...
- Jenkins学习记录
参考资料 官方文档 用MSBuild和Jenkins搭建持续集成环境(1) 用MSBuild和Jenkins搭建持续集成环境(2) 构建基于Jenkins + Github的持续集成环境 Jenkin ...
- PHP 错误与异常 笔记与总结(2)错误(Fatal)
(接上) d.Fatal error 致命级别的错误 —— 程序终止执行 [例7]调用一个未定义的方法 <?php echo md6('dee'); echo 'continue'; 输出: ( ...
- MySQL 数据库设计 笔记与总结(4)维护优化
[维护和优化的工作] ① 维护数据字典 ② 维护索引 ③ 维护表结构 ④ 在适当的时候对表进行水平拆分或垂直拆分 [维护数据字典] a 使用第三方工具对数据字典进行维护 b 利用数据库本身的备注字段来 ...
- 【转载】C编译过程概述
gcc:http://www.cnblogs.com/ggjucheng/archive/2011/12/14/2287738.html#_Toc311642844 gdb:http://www.cn ...
- Natural Language Toolkit
http://www.nltk.org/ >>> import nltk >>> nltk.download()
- Jquery手册
1.jQuery 选择器: 选择器 实例 选取 * $("*") 所有元素 #id $("#lastname") id="lastname" ...
- 非模态对话框的PreTranslateMessage() 没有用,无法进去
非模态对话框的的PreTranslateMessage确实进不去, 自然也无法用重载PreTranslateMessage的方法来响应键盘消息. 可以用Hook的方法来使其生效. http://bbs ...
- discuz函数解析--写日志
public static function writelog($file, $log) { global $_G; $yearmonth = dgmdate(TIMESTAMP, 'Ym', $_G ...
- C#5.0 .net 4.5示例
//filename: MathOperations.cs using System; using System.Collections.Generic; using System.Linq; usi ...