__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)的更多相关文章

  1. __declspec(dllexport) 和 __declspec(dllimport)的区别

    最近看MXNet的源码,其中c_api.h中发现遇到__declspec(dllexport) 和 __declspec(dllimport). __declspec(dllexport)用于导出符号 ...

  2. 理解 __declspec(dllexport)和__declspec(dllimport)

    1.解决的问题: 考虑下面的需求,使用一个方法,一个是提供者,一个是使用者,二者之间的接口是头文件.头文件中声明了方法,在提供者那里方法应该被声明为__declspec(dllexport),在使用者 ...

  3. __declspec(dllexport) 和 __declspec(dllimport)的作用

    operatordll.h #include <iostream> #ifndef _WIN32 #define DLL_EXPORT#else #ifdef OPERATORDLL_EX ...

  4. 通过宏定义将__declspec(dllexport)与__declspec(dllimport)的转化,实现库代码和使用代码使用同一份头文件

    我们知道,在VC编程中,如果要编译成动态链接库,需要将函数.变量.类等导出,这时使用__declspec(dllexport).使用动态链接库时,需要在声明的时候有使用__declspec(dllim ...

  5. 【转载】 __declspec(dllexport) 和__declspec(dllimport)

    转自:http://www.cppblog.com/Dutyboy/archive/2010/11/15/133699.html __declspec(dllexport)   __declspec( ...

  6. __declspec(dllexport)和__declspec(dllimport) (——declspec方法创建dll的方法已验证ok)

    转载:https://www.cnblogs.com/chengbing2011/p/4084125.html __declspec(dllimport)和__declspec(dllexport)经 ...

  7. __declspec(dllexport)

    __declspec(dllexport) (2010-06-17 10:04:28) 转载▼ 标签: __declspec dllexport 导出 it 分类: C 先看代码:以下是在dev-c+ ...

  8. extern "C" __declspec(dllexport) __declspec(dllimport) 和 def

    原文:extern "C" __declspec(dllexport) __declspec(dllimport) 和 def 前面的extern "C"  _ ...

  9. __declspec(dllexport) & __declspec(dllimport)

    __declspec(dllexport) 声明一个导出函数,是说这个函数要从本DLL导出.我要给别人用.一般用于dll中 省掉在DEF文件中手工定义导出哪些函数的一个方法.当然,如果你的DLL里全是 ...

随机推荐

  1. easyui numberbox不可编辑

    今天又遇到了给easyui中numberbox设置不可编辑的功能,在(http://www.jeasyuicn.com/api/docTtml/index.htm)API中找到了一个方法:

  2. 【转】Nginx+php-fpm+MySQL分离部署详解

    转:http://www.linuxidc.com/Linux/2015-07/120580.htm Nginx+php-fpm+MySQL分离部署详解 [日期:2015-07-26] 来源:Linu ...

  3. BZOJ4033 [HAOI2015]T1

    令$f[p][i]$表示以$p$为根的子树内,选了$i$个黑点,剩下的都是白点的这个子树内贡献的答案 如果$p$的子树都算出来了,只要计算$p$与$fa[p]$之间的边对答案的贡献就好了,贡献是$di ...

  4. Spring学习(二)——Spring中的AOP的初步理解[转]

      [前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring. ...

  5. 在SQLite中创建数据库时总是提示错误?

    答案:原先以为是因为编码影响的其实不是,是因为逗号和分号的原因,不是标准的英文状态下的格式

  6. qml ios长按晃动

    WidgetModel.qml import QtQuick 1.0 ListModel { ListElement { icon: "Images/widget1.png"; g ...

  7. NOIP2005 等价表达式 解题报告

    明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数表达式是和 ...

  8. java udp网络编程

    import java.net.*; /* 通过UDP传输发送文字数据 1.建立socket服务 2.提供数据,并封装到数据包中 3.通过sokect服务的发送功能,将数据包发送出去 4.关闭资源 * ...

  9. iOS开发中XML的DOM和SAX解析方法

    一.介绍 dom是w3c指定的一套规范标准,核心是按树形结构处理数据,dom解析器读入xml文件并在内存中建立一个结构一模一样的“树”,这树各节点和xml各标记对应,通过操纵此“树”来处理xml中的文 ...

  10. SharePoint开发 - 自定义导航菜单(三)附其他代码

    博客地址 http://blog.csdn.net/foxdave 接上篇点击打开链接 LeftNavGroupTemplate.cs internal class LeftNavGroupTempl ...