转自: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"的更多相关文章

  1. DLL中导出函数的两种方式(dllexport与.def文件)

    DLL中导出函数的声明有两种方式: 一种方式是:在函数声明中加上__declspec(dllexport): 另外一种方式是:采用模块定义(.def)文件声明,(.def)文件为链接器提供了有关被链接 ...

  2. (转)DLL中导出函数的两种方式(dllexport与.def文件)

    DLL中导出函数的两种方式(dllexport与.def文件)http://www.cnblogs.com/enterBeijingThreetimes/archive/2010/08/04/1792 ...

  3. 【转】DLL中导出函数的两种方式(dllexport与.def文件)

    DLL中导出函数的两种方式(dllexport与.def文件) DLL中导出函数的声明有两种方式: 一种方式是:在函数声明中加上__declspec(dllexport):另外一种方式是:采用模块定义 ...

  4. VC 使用msxml6.dll动态链接库中的函数读写XML文件

    VC 使用msxml6.dll动态链接库中的函数读写XML文件 目录 1 引言 2 .dll使用方法 3 常用函数总结 4 实例应用 5 运行效果预览 6 补充说明 7 不足之处 8 更新   引言: ...

  5. 理解函数式编程中的函数组合--Monoids(二)

    使用函数式语言来建立领域模型--类型组合 理解函数式编程语言中的组合--前言(一) 理解函数式编程中的函数组合--Monoids(二) 继上篇文章引出<范畴论>之后,我准备通过几篇文章,来 ...

  6. Windows编程中回调函数的使用心得(MFC篇)

    回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数.回调函数不是由该函数的实现方直接调用,而是在特定 ...

  7. C++ DLL中导出函数的声明的方法

    定义: TESTDLLEXPORT_API int fnTestDllExport(void); TESTDLLEXPORT_API int fnTestCall(void); TESTDLLEXPO ...

  8. MFC DLL中导出函数模板

    //my.h struct AFX_EXT_CLASS B { }; struct AFX_EXT_CLASS C { }; class AFX_EXT_CLASS A { public: templ ...

  9. 【转】 嵌入式C语言编程中Inline函数的应用

    源地址:https://blog.csdn.net/vigour1000/article/details/9622037 有一段儿时间没写写经验笔记了,哎,也是自己这一段时间以来(其实最近一直是这个状 ...

随机推荐

  1. Qt 等待一段时间例如1s

    QTime dieTime = QTime::currentTime().addMSecs(1000); while( QTime::currentTime() < dieTime ) QCor ...

  2. 程序记录2(设置MapID)

    try{ INIT_PLUG I_MongoDB* i = NEW(MongoDB); /*[注] 若自定义错误消息的数组长度必需指定为MAX_ERROR_SIZE*/ //char errmsg[M ...

  3. pdb文件及引发的思考

    最初只想知道线上iis里需要不需要pdb文件,了解部分之后对于.net底层产生了浓厚的兴趣,看了一点点资料 资料来源: https://www.cnblogs.com/itech/archive/20 ...

  4. Java操作文件转码

    package downloadTest; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.F ...

  5. Python全栈day10(运算符)

    一,运算符 + - * . ** % // 二,in 和not in 一个字符串包含多个字符可以通过in判断字符是否属于改字符串 >>> name = "zhangsan& ...

  6. react-native 学习(三)

    上一次讲到了react-native 的配置环境 和 如何去进行调试,这一次我们说一说,关于react-native的 样式兼容问题. 由于iphonex的发售,在兼容的时候,我门也需要去考虑ipho ...

  7. JavaWeb配置错误页面

    我们在实际开发过程中经常会遇到程序出错的各种情况,比如最常见的404错误,500错误等等相关错误,服务器默认会将错误的信息直接显示在浏览器的页面上,如下图所示: 不管是谁如果看到这种情况的话,顿时就会 ...

  8. NGINX优化参数

    (1)nginx运行工作进程个数,一般设置cpu的核心或者核心数x2 如果不了解cpu的核数,可以top命令之后按1看出来,也可以查看/proc/cpuinfo文件 grep ^processor / ...

  9. python and 我爱自然语言处理

    曾经因为NLTK的 缘故开始学习Python,之后渐渐成为我工作中的第一辅助脚本语言,虽然开发语言是C/C++,但平时的很多文本数据处理任务都交给了Python.离 开腾讯创业后,第一个作品课程图谱也 ...

  10. Django 框架之Form组件

    1. Django的Form主要具有以下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交的数据 初始化页面显示内容 2. 第一个案例: # 第一步: 创建 ...