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模块定义(用于导出函数)文件,此时若使用将不得不调用 ...
随机推荐
- Sqlmap注入技巧集锦
当我们注射的时候,判断注入 http://site/script?id=10 http://site/script?id=11-1 # 相当于 id=10 http://site/script?id= ...
- 关于0x000000c2问题解决方法
首先大家要用进入PE系统,按照我说的顺序做就可以解决了! 1,进入PE后找到系统盘,默认一般为C盘-->进入WINDOWS文件夹-->进入system32文件夹-->找到regedt ...
- 各种常用的JSON接口,开动你的大脑你就可以做出各种应用,值得收藏
各种常用的JSON接口,开动你的大脑你就可以做出各种应用,值得收藏 浏览:1412 发布日期:2014/01/27 分类:技术分享 这里为大家搜集了一些能够返回JSON格式的服务接口.部分需要用J ...
- ArcGIS Server发布服务,打包成功,发布失败
打包成功,发布失败 部分解决方案: ① 查看Server对于源数据所在文件夹是否有读写权限,若无赋予Server账户至少读写权限.读写权限的赋予:对应存放数据的文件夹上右键→属性→ 安全 赋予ar ...
- yum 安装mysql5.6
系统centos5.5 进入http://dev.mysql.com/downloads/repo/,下载RedHat Enterprise Linux 5 / Oracle Linux 5版. 点击 ...
- SQLite(快速上手版)笔记
原文 1. SQL语法关键字 关键字 描述 Create Table 创建数据表 Alter Table 修改数据表 Drop Table 删除数据表 Create Index 创建索引 Drop I ...
- volatile in thread
public class TestCalc { public static void main(String[] args) { class StoppableThread extends Threa ...
- jenkins password reset,and git integration
0. SSH to server 1. Edit /opt/bitnami/apps/jenkins/jenkins_home/config.xml 2. set userSecurity to ...
- 【译】Android系统架构
让我们来快速预览一下整个android系统的架构.从下面的图中我们可以发现,这个架构分为几个不同的层,底层为上一层提供服务. Linux Kernel android系统建立在一个坚固的基石上:Li ...
- .NET 可空值类型
Microsoft在CLR中引入了可空值类型(nullable value type)的概念. FCL中定义System.Nullable<T>类如下: [Serializable,Str ...