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模块定义(用于导出函数)文件,此时若使用将不得不调用 ...
随机推荐
- HTTP POST, PUT PATCH
POST = 新增 GET = 讀取 PUT = 更新 DELETE = 刪除 PUT 会在地址栏显示参数信息,不安全! 理解POST和PUT的区别,顺便提下RESTfu 这两个方法咋一看都可以更新资 ...
- Virtualbox虚拟Ubuntu共享文件夹设置
1. 启动ubuntu, 然后先virtualbox的安装增强功能,菜单:“设备(D)”-> "安装增强功能":然后进入ubuntu 系统,安装Vboxadditions_. ...
- link them together by means of pointers
Computer Science An Overview _J. Glenn Brookshear _11th Edition An alternative to storing a heteroge ...
- nginx proxy_pass
在nginx中配置proxy_pass时,如果是按照^~匹配路径时,要注意proxy_pass后的url最后的/,当加上了/,相当于是绝对根路径,则nginx不会把location中匹配的路径部分代理 ...
- 【转】CodeIgniter定义自己的Helper和Helper的方法
最近做程序,采用了PHP+CodeIgniter框架,总体来说这框架很轻而且上手也很快的. 首先,说下如何定义自己的Helper,个人理解helper其实就是定义函数方法. 如果要建个全新的自己的He ...
- 地图API使用文档-以腾讯地图为例
目录 腾讯地图API 2 1.API概览... 2 1.1 WebService API(官网注明是beta版本,可能不稳定,慎用):... 2 1.2 URL API:... 2 1.3 静态图AP ...
- python 中del 的用法
python中的del用法比较特殊,新手学习往往产生误解,弄清del的用法,可以帮助深入理解python的内存方面的问题. python的del不同于C的free和C++的delete. 由于pyth ...
- HBase的架构以及各个模块的功能
一:整体架构 1.体系结构 2.物理模型 3.存储体系 regionserver->region->多个store(列簇)->一个memstore和多个storefile 4.HDF ...
- 流媒体学习四------- ortp队列的实现
在ortp中实现了一个通用的队列,每一个队列包括三个实体,分别是队列.消息块和数据块,这三个实体分别对应queue_t.msgb和datab结构体. queue_t的定义如下所示: typedef s ...
- 转:ASP.NET MVC利用TryUpdateModel来做资料更新 (二)
前言 第一篇說明了 TryUpdateModel 的簡單的應用,除了可指定更新的欄位之外也可排除更新特定的欄位,而因為可搭配 Metadata 做欄位驗證為資料又做了一層把關,但在 ASP.NET M ...