浅谈__declspec(dllexport)和__declspec(dllimport)
__declspec(dllimport)和__declspec(dllexport)经常是成对的,在动态链接库中__declspec(dllexport)导出dll中的成员,__declspec(dllimport)导入外部dll中的成员。
但是有时候不使用dllimport和dllexport也能实现个基本的导出导入功能, 它们具有的功能如下:
1.dllimport/dllexport可以导入或者导出动态链接库中的全局变量,当然是用extern也可以实现同样的功能;
2.dllimport/dllexport的作用主要体现在导出类的静态成员方面,如果不使用它们,无法在正常是用外部dll中类的静态成员函数;
3.隐式使用dll时,不加dllimport/dllexport也是可以,使用上没什么区别,只是在生成的二进制代码上稍微有点效率损失;
4.使用dllimport/dllexport还可以体现编程语言的对称美。
以下是一个Demo实例:
====================================.h文件如下[DllExport.h]:================================================
#ifdef DLLEXPORT_EXPORTS
#define DLLEXPORT_API __declspec(dllexport)
#else
#define DLLEXPORT_API __declspec(dllimport)
#endif // class从dll中导出Demo
class DLLEXPORT_API CDllExport {
public: CDllExport(void);
}; //变量从dll中导出Demo
extern DLLEXPORT_API int nDllExport; //函数从dll中导出Demo
DLLEXPORT_API int fnDllExport(void);
====================================.cpp文件如下[DllExport.cpp]:==============================================
#include "DllExport.h" // 变量从Dll中导出Demo
DLLEXPORT_API int nDllExport=; // 函数从Dll中导出Demo
DLLEXPORT_API int fnDllExport(void) { return ; } // 类从Dll中导出Demo,以下为导出类的构造函数
CDllExport::CDllExport() { return; }
====================================调用文件如下[DemoEntry.cpp]:=============================================
#include"DllExport.h"
#include<iostream> int _tmain(int argc, _TCHAR* argv[])
{
int returncnt= fnDllExport();
std::cout<<returncnt<<std::endl;
system("pause");
return ; }
====================================================================================================
调用Dll过程编译器设置如下:
同样,使用.def文件也可以导出dll中的函数供外部调用,关于.def的使用如下:
1.LIBRARY语句说明.def文件相应的DLL;
2.EXPORTS语句后列出要导出函数的名称。可以在.def文件中的导出函数名后加@n,表示要导出函数的序号为n(在进行函数调用时,这个序号将发挥其作用);
3.def文件中的注释由每个注释行开始处的分号 (;) 指定,且注释不能与语句共享一行
以下是使用.def 文件导出DLL的Demo实例:
====================================.cpp文件如下[APIExport.cpp]:=============================================
int nTest=;//全局变量 int AddAndMulti(int a,int b)
{
return (a+b)*nTest;
} int _stdcall SubAndMulti(int a,int b)
{
return (a-b)*nTest;
} int _cdecl Multiply(int a,int b)
{
return a*b;
}
====================================.def文件如下[DllExport.def]:==============================================
LIBRARY DllExport_def
EXPORTS
AddAndMulti @3
SubAndMulti @5
Multiply @1
nTest DATA
====================================.cpp调用代码[DllLoadEntry.cpp]:============================================
// DllLoadEntry.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <iostream> using namespace std; //引用dll中的全局变量
extern int _declspec(dllimport) nTest; //声明函数,需与Dll中的函数定义一致(包括其函数调用修饰词)
int AddAndMulti(int a,int b); int _stdcall SubAndMulti(int a,int b); int _cdecl Multiply(int a,int b); //#pragma comment(lib,"DllExport_def.lib")
int _tmain(int argc, _TCHAR* argv[])
{
nTest=; cout<<AddAndMulti(,)<<endl;
cout<<SubAndMulti(,)<<endl;
cout<<Multiply(,)<<endl; system("pause"); return ;
}
====================================================================================================
编译环境设置如下:
当然也可以在代码中添加 #pragma comment(lib,"DllExport_def.lib")实现同样的效果,DLL和调用的exe在同一个目录下。
def和__declspec的使用区别:
VC++编译器会对__declspec导出的函数进行一定的变化,如下:__declspec(dllexport) int __stdcall Add()会转换为Add@0(),对于外部调用程序也是VC++时,只需要将编译产生的lib文件提供给调用者即可,而如果提供给语言程序调用,就不是那么方便了。此时,使用.def文件就可以让编译器不会对导出的函数名称进行修改。
浅谈__declspec(dllexport)和__declspec(dllimport)的更多相关文章
- __declspec(dllexport) 和 __declspec(dllimport)的区别
最近看MXNet的源码,其中c_api.h中发现遇到__declspec(dllexport) 和 __declspec(dllimport). __declspec(dllexport)用于导出符号 ...
- 理解 __declspec(dllexport)和__declspec(dllimport)
1.解决的问题: 考虑下面的需求,使用一个方法,一个是提供者,一个是使用者,二者之间的接口是头文件.头文件中声明了方法,在提供者那里方法应该被声明为__declspec(dllexport),在使用者 ...
- __declspec(dllexport) 和 __declspec(dllimport)的作用
operatordll.h #include <iostream> #ifndef _WIN32 #define DLL_EXPORT#else #ifdef OPERATORDLL_EX ...
- 通过宏定义将__declspec(dllexport)与__declspec(dllimport)的转化,实现库代码和使用代码使用同一份头文件
我们知道,在VC编程中,如果要编译成动态链接库,需要将函数.变量.类等导出,这时使用__declspec(dllexport).使用动态链接库时,需要在声明的时候有使用__declspec(dllim ...
- 【转载】 __declspec(dllexport) 和__declspec(dllimport)
转自:http://www.cppblog.com/Dutyboy/archive/2010/11/15/133699.html __declspec(dllexport) __declspec( ...
- __declspec(dllexport)和__declspec(dllimport) (——declspec方法创建dll的方法已验证ok)
转载:https://www.cnblogs.com/chengbing2011/p/4084125.html __declspec(dllimport)和__declspec(dllexport)经 ...
- __declspec(dllexport)
__declspec(dllexport) (2010-06-17 10:04:28) 转载▼ 标签: __declspec dllexport 导出 it 分类: C 先看代码:以下是在dev-c+ ...
- extern "C" __declspec(dllexport) __declspec(dllimport) 和 def
原文:extern "C" __declspec(dllexport) __declspec(dllimport) 和 def 前面的extern "C" _ ...
- __declspec(dllexport) & __declspec(dllimport)
__declspec(dllexport) 声明一个导出函数,是说这个函数要从本DLL导出.我要给别人用.一般用于dll中 省掉在DEF文件中手工定义导出哪些函数的一个方法.当然,如果你的DLL里全是 ...
随机推荐
- 个人介绍和GitHub
基本信息: 姓名:陈晖 学号:1413042068 班级:网工143 兴趣爱好:看小说,打游戏,听古风音乐,打羽毛球,骑行等 个人编程能力不高,写的代码都是作业…… GitHub注册流程: 对于Git ...
- js——倒计时
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- YouTube技术架构
谈不上翻译,就是摘录 1 billion video views per day 1.Apache 2.Python 3.Linux (SuSe) 4.MySQL 5.psyco, a dynamic ...
- 安卓Json介绍(转)。
1.JSON(JavaScript Object Notation) 定义: 一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性.业内主流技术为其提供了完整的解决方案(有点类似于正则表达式, ...
- Oracle练习题(1~19)
1. 查询Student表中的所有记录的Sname.Ssex和Class列. 2. 查询教师所有的单位即不重复的Depart列. 3. 查询Student表的所有记录. 4. 查询Score表中成绩在 ...
- 北邮新生排位赛1解题报告a-c
<div class="page-header" style="padding-bottom: 9px; margin: 20px 0px 30px; border ...
- DrawerLayout一个简单的实例(与ActionBar无关)
官方的Demo里有DrawerLayout的例子,涉及到ActionBar,这里不用ActionBar,手痒,写个超级简单的小Demo,备着以后或许会用到. 详细的内容,可以访问:http://blo ...
- 采用EntLib5.0(Unity+Interception+Caching)实现项目中可用的Caching机制
看了园子里很多介绍Caching的文章,多数都只介绍基本机制,对于Cache更新和依赖部分,更是只简单的实现ICacheItemRefreshAction接口,这在实际项目中是远远不够的.实际项目中, ...
- 移动设备和SharePoint 2013 - 第5部分:自定义应用
博客地址:http://blog.csdn.net/foxdave 原文地址 在该系列文章中,作者展示了SharePoint 2013最显著的新功能概观--对移动设备的支持. 该系列文章: 移动设备和 ...
- python 第三方库 chardet
chardet是一个非常优秀的编码识别模块.chardet 是python的第三方库,需要下载和安装,放在python安装根目录\Lib\site-packages下面 import chardet ...