在DLL编程中,导出函数为什么需要extern "C"
转自:http://blog.csdn.net/zhongjling/article/details/8088664
一般来讲,在DLL编程过程中,对于导出的函数前 都需要加入 extern “C”,
extern 表示这是个全局函数,可以供各个其他的函数调用;
“C” 表示编译时按照 C编译器的方式进行编译,而不是C++。 C++的编译方式考虑了函数重载,所以对函数名进行了新的修饰,产生了所谓的破坏性命名。
不过,也有特殊情况,有三种例外情况可以不加extern “C”:
1、如果不是用C++编译器而是用C编译DLL,名字不会变,可以不加extern "C"
2、如果DLL的使用者知道是用C++编译器编译DLL,不加extern “C”也可以,因为他知道名字改变的规则。调用GetProcAddress时,把函数名字改了就是了,改为修饰后的函数名。 如 fnDll1 改为 ?fnDll1@@YAHXZ。
例子关键代码如下:
----------------------------
DLL部分:
// This is an example of an exported function.
DLL1_API int __cdecl fnDll1(void)
{
return 42;
}
输出的修饰函数名为?fnDll1@@YAHXZ
DLL1_API int __cdecl fnDll1(int a)
{
return 42+a;
}
输出的修饰函数名为?fnDll1@@YAHH@Z
-----------------------------
EXE部分:
HINSTANCE hModule = LoadLibrary("dll1.dll");
ASSERT(hModule);
typedef int (*fnDll1)();
fnDll1 pfnDll1 = NULL;
//VERIFY(pfnDll1 = (fnDll1)::GetProcAddress(hModule, "fnDll1"));
VERIFY(pfnDll1 = (fnDll1)::GetProcAddress(hModule, "?fnDll1@@YAHXZ"));
ASSERT(pfnDll1() == 42);
typedef int (*fnDll2)(int);
fnDll2 pfnDll2 = NULL;
VERIFY(pfnDll2 = (fnDll2)::GetProcAddress(hModule, "?fnDll1@@YAHH@Z"));
ASSERT(pfnDll2(3) == 45);
---------------------------
3.上面的2太麻烦了。所以还有一种方法是使用def文件。
(如果DLL使用的是def文件,要删除TestDll.h文件中关键字extern "C",即2者是不能共存的)。
def 文件(模板定义文件),第一个语句必须是 LIBRARY 语句,指出DLL的名字;
EXPORTS语句 列出被导出函数的名字;将要输出的函数罗列出来,这个函数名字必须与定义函数的名字完全一致,如此既可以得到
一个没有任何修饰符的函数名了。
被导出的函数 可以和一个序号相对应。定义序号时必须在数字前加一个@。例如 isRUINIan @1 //IsRuiNian 函数对应序号为 1
这样的话,我们既可以GetProAddress(hinstance,“IsRuiNian”),也可以 GetProAddress(hinstance,(LPCSTR)1)实现调用。
参考:http://topic.csdn.net/t/20021012/17/1090973.html
http://www.qqgb.com/program/vc/vcjq/program_166495.html
在DLL编程中,导出函数为什么需要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中导出函数的两种方式(dllexport与.def文件)
DLL中导出函数的两种方式(dllexport与.def文件) DLL中导出函数的声明有两种方式: 一种方式是:在函数声明中加上__declspec(dllexport):另外一种方式是:采用模块定义 ...
- VC 使用msxml6.dll动态链接库中的函数读写XML文件
VC 使用msxml6.dll动态链接库中的函数读写XML文件 目录 1 引言 2 .dll使用方法 3 常用函数总结 4 实例应用 5 运行效果预览 6 补充说明 7 不足之处 8 更新 引言: ...
- 理解函数式编程中的函数组合--Monoids(二)
使用函数式语言来建立领域模型--类型组合 理解函数式编程语言中的组合--前言(一) 理解函数式编程中的函数组合--Monoids(二) 继上篇文章引出<范畴论>之后,我准备通过几篇文章,来 ...
- Windows编程中回调函数的使用心得(MFC篇)
回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数.回调函数不是由该函数的实现方直接调用,而是在特定 ...
- C++ DLL中导出函数的声明的方法
定义: TESTDLLEXPORT_API int fnTestDllExport(void); TESTDLLEXPORT_API int fnTestCall(void); TESTDLLEXPO ...
- MFC DLL中导出函数模板
//my.h struct AFX_EXT_CLASS B { }; struct AFX_EXT_CLASS C { }; class AFX_EXT_CLASS A { public: templ ...
- 【转】 嵌入式C语言编程中Inline函数的应用
源地址:https://blog.csdn.net/vigour1000/article/details/9622037 有一段儿时间没写写经验笔记了,哎,也是自己这一段时间以来(其实最近一直是这个状 ...
随机推荐
- ORA-12899: value too large for column
ORA-12899: value too large for column "SOAU"."SJQY_QTSBSPEC"."PROPERTY_6&qu ...
- 【BZOJ3238】[Ahoi2013]差异 后缀数组+单调栈
[BZOJ3238][Ahoi2013]差异 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Ou ...
- Caused by: java.lang.ClassNotFoundException[android的终极解决错误]
from:http://blog.csdn.net/changemyself/article/details/7861525 08-13 18:29:22.924: E/AndroidRuntime( ...
- vue+node+mongoDB火车票H5(七)-- nodejs 爬12306查票接口
菜鸟一枚,业余一直想做个火车票查票的H5,前端页面什么的已经写好了,node+mongoDB 也写了一个车站的接口,但 接下来的爬12306获取车次信息数据一直卡住,网上的爬12306的大部分是pyt ...
- vue 二级列表折叠面板
请求出来的数据是二级列表,需要点击一级列表展开相应的二级列表 data(){ return { info: [ {name:'一级菜单1',lists:[{price:1},{price:2}]}, ...
- 进击的RecyclerView入门三(要是能拖动就好了)
还是接着上一讲"进击的RecyclerView入门二(来点小装饰?)",在上一讲中我们学到了怎么给不同的Item定制不同的外观,但貌似那个蓝色的框实在太丑了,咱还是把它干了吧. @ ...
- Educational Codeforces Round 25 E. Minimal Labels&&hdu1258
这两道题都需要用到拓扑排序,所以先介绍一下什么叫做拓扑排序. 这里说一下我是怎么理解的,拓扑排序实在DAG中进行的,根据图中的有向边的方向决定大小关系,具体可以下面的题目中理解其含义 Educatio ...
- UISearchBar 详解
UISearchBar 详解 最近用到搜索功能.于是,经过不断的研究,终于,有点懂了. 那就来总结一下吧,好记性不如烂笔头! 搜索,无疑可以使用UISearchBar控件! 那就先了解一下UISe ...
- nodejs(三)上之express
express 简介 Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具. 使用 Express 可以快速 ...
- Python中的推导式(列表推导式、字典推导式、集合推导式)
推导式comprehensions(又称解析式),是Python的一种独有特性.推导式是可以从一个数据序列构建另一个新的数据序列的结构体. 共有三种推导,在Python2和3中都有支持: 列表(lis ...