浅谈__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里全是 ...
随机推荐
- easyui numberbox不可编辑
今天又遇到了给easyui中numberbox设置不可编辑的功能,在(http://www.jeasyuicn.com/api/docTtml/index.htm)API中找到了一个方法:
- 【转】Nginx+php-fpm+MySQL分离部署详解
转:http://www.linuxidc.com/Linux/2015-07/120580.htm Nginx+php-fpm+MySQL分离部署详解 [日期:2015-07-26] 来源:Linu ...
- BZOJ4033 [HAOI2015]T1
令$f[p][i]$表示以$p$为根的子树内,选了$i$个黑点,剩下的都是白点的这个子树内贡献的答案 如果$p$的子树都算出来了,只要计算$p$与$fa[p]$之间的边对答案的贡献就好了,贡献是$di ...
- Spring学习(二)——Spring中的AOP的初步理解[转]
[前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring. ...
- 在SQLite中创建数据库时总是提示错误?
答案:原先以为是因为编码影响的其实不是,是因为逗号和分号的原因,不是标准的英文状态下的格式
- qml ios长按晃动
WidgetModel.qml import QtQuick 1.0 ListModel { ListElement { icon: "Images/widget1.png"; g ...
- NOIP2005 等价表达式 解题报告
明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数表达式是和 ...
- java udp网络编程
import java.net.*; /* 通过UDP传输发送文字数据 1.建立socket服务 2.提供数据,并封装到数据包中 3.通过sokect服务的发送功能,将数据包发送出去 4.关闭资源 * ...
- iOS开发中XML的DOM和SAX解析方法
一.介绍 dom是w3c指定的一套规范标准,核心是按树形结构处理数据,dom解析器读入xml文件并在内存中建立一个结构一模一样的“树”,这树各节点和xml各标记对应,通过操纵此“树”来处理xml中的文 ...
- SharePoint开发 - 自定义导航菜单(三)附其他代码
博客地址 http://blog.csdn.net/foxdave 接上篇点击打开链接 LeftNavGroupTemplate.cs internal class LeftNavGroupTempl ...