在DLL编程中,导出函数为什么需要extern "C"
来源:互联网 发布:历史大事年表知乎 编辑:程序博客网 时间:2024/05/22 22:23
一般来讲,在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
问:要说在不同编程语言之间共享dll文件的导出函数的话,在函数前加 WINAPI 就够了,为什么要加 extern "C"
防止C++编译器的“名字破坏”特性
extern "C"的作用是,使编译器按照c的方式生成函数名,c的方式实际的函数名和你写的一样。如果没有这个,则按照c++的方式生成函数名,这样实际的函数名(LoadLibrary方式GetProcAddress传入的函数名)和你写得函数名不一样,这样你用LoadLibrary、GetProcAddress这种方式调用dll就不成功。
但是用引入库的方式调用,则编译器自动转换函数名,所以总是没有问题。
http://www.qqgb.com/program/vc/vcjq/program_166495.html
- 在DLL编程中,导出函数为什么需要extern "C"
- 在DLL编程中,导出函数为什么需要extern "C"
- 在DLL编程中,导出函数为什么需要extern "C"
- extern "C"在DLL导出函数时有什么作用?
- DLL 的编写,导出函数 DLL 中.def和extern c的作用
- 为什么c++程序调用c编译器编译的函数需要在调用前加上extern“C”
- Windows/MFC_中dll __stdcall,__cdcel,extern c 和导出函数名
- 通过GetProcAddress函数动态调用dll中地函数,是否必须通过extern C声明导出函数?
- 在C++中调用被C编译器编译后的函数,为什么要加extern "C"
- 在C++中调用C编译器编译过的函数时,为什么要使用"extern C"?
- 编程c++dll , DLL 的编写,导出函数 ,使用函数
- 在C++ 程序中调用被 C 编译器编译后的函数,为什么要加 extern
- 为什么在C++中需要虚函数
- 为什么在头文件中有extern "C" ?
- 为什么在头文件中有extern "C" ? .
- 在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”?
- 在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”?
- 经典面试题目--在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”?
- 原始的爱情
- 层次聚类算法及其实现
- 主流WiFi芯片与性能简介
- Word自动编号多级标题设置
- 枚举
- 在DLL编程中,导出函数为什么需要extern "C"
- 如何构建研发质量管理体系?
- 【HDU-2639】Bone Collector II(背包)
- Caffe for Windows 训练cifar10 VS2013
- iOS pushnotification
- 如何正确使用C++多重继承
- 使用CMD命令提示符配置IP
- 几种常见的过程模型
- vmware 12 虚拟机安装mac osx 10.11.3 分辨率设置