c语言def_ext作用,在DLL编程中,导出函数为什么需要extern "C"

"本文详细讲解了DLL编程中导出函数的必要性,extern""C""的作用,以及三种无需extern""C""的情况,包括C编译器、DLL使用者明确编译方式和使用.def文件。此外,还介绍了DLL导出的两种方式:dllexport与.def文件,并提供了代码示例。"
摘要由CSDN通过智能技术生成

转自: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)实现调用。

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 更新   引言: ...

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 有一段儿时间没写写经验笔记了,哎,也是自己这一段时间以来(其实最近一直是这个状 ...

C# DumpBin使用 查看反射C++ dll 动态链接库中的函数

DumpBin是Microsoft提供的一个用于查看.exe..dll文件信息的工具,其位于: C:\Program Files (x86)\Microsoft Visual Studio 10.0\ ...

随机推荐

autofs自动挂载

autofs是根据需要自动挂载,默认5分钟不使用自动卸载挂载点!nfs,smb,iso,sd*的挂载 环境:RHEL6.5/Centos6.5    172.24.0.25 01.安装autofs y ...

js分页小结

今天解决了JS分页的问题1 页码 给每页的内容套一个相同的类名 通过选择器加上.length或者.size() 来获得总页数2当前页的页码可以使用each(function(index,DOMsss ...

【技术贴】解决使用maven jetty启动后无法加载修改过后的静态资源

如何使用jetty自动热部署修改后的所有文件,比如js,jpg,class等,哇咔咔 太爽啦比tomcat舒服多了. jetty模式是不能修改js文件的,比如你现在调试前端js,发现在myeclips ...

SaaS是个不错的生意模式和创业的选择(独立SAAS厂商的三大优势)

1. 软件独特而又强大,界面绝美2. 数据存在本国3. 数据不留底 4. 可随时寻求卖身或者合作,不受制于人 --------------------------------------------- ...

windows下实现linux的远程访问以及linux上文件的上传和下载

在网络性能.安全性.可管理性上,Linux有着其他系统无法比拟的强大优势,而服务器对这些方面要求特别高,因此Linux常常被用来做服务器使用.而当我们需要维护linux服务器的时候,就需要远程访问li ...

Ztree节点增加删除修改和Icheck的用法

简介 官方文档:http://www.treejs.cn/v3/api.php zTree 是一个依靠 jQuery 实现的多功能 “树插件”, 而且拥有较好的浏览器兼容性,有着丰富的功能以及可以自定 ...

Mac OS X 下安装使用 Docker

它依赖于 LXC(Linux Container),能从网络上获得配置好的 Linux 镜像,非常容易在隔离的系统中运行自己的应用.也因为它的底层核心是个 LXC,所以在 Mac OS X 下需要在 ...

P3466 [POI2008]KLO-Building blocks

目录 题目 思路 错误 代码 题目 luogu csdn好像限制了展开博客次数,真的好xx 思路 显然一段区间内的值一定是他的中位数 少一点比多一点好 然后就可以枚举区间了 区间答案为 val[mid ...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值