转载:https://www.cnblogs.com/chengbing2011/p/4084125.html

__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实例:

创建win的dll项目空项目名为DllExport

====================================.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=0; // 函数从Dll中导出Demo
DLLEXPORT_API int fnDllExport(void) { return 42; } // 类从Dll中导出Demo,以下为导出类的构造函数
CDllExport::CDllExport() { return; }

创建win的exe项目名为DemoEntry

====================================调用文件如下[DemoEntry.cpp]:=============================================

#include"DllExport.h"
#include<iostream> int _tmain(int argc, _TCHAR* argv[])
{
int returncnt= fnDllExport();
std::cout<<returncnt<<std::endl;
system("pause");
return 0; }

====================================================================================================

调用Dll过程编译器设置如下:

同样,使用.def文件也可以导出dll中的函数供外部调用,关于.def的使用如下:

1.LIBRARY语句说明.def文件相应的DLL;

2.EXPORTS语句后列出要导出函数的名称。可以在.def文件中的导出函数名后加@n,表示要导出函数的序号为n(在进行函数调用时,这个序号将发挥其作用);

3.def文件中的注释由每个注释行开始处的分号 (;) 指定,且注释不能与语句共享一行

以下是使用.def 文件导出DLL的Demo实例:

====================================.cpp文件如下[APIExport.cpp]:=============================================

int nTest=1;//全局变量  

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=2; cout<<AddAndMulti(1,2)<<endl;
cout<<SubAndMulti(3,4)<<endl;
cout<<Multiply(4,5)<<endl; system("pause"); return 0;
}

====================================================================================================

编译环境设置如下:

 

当然也可以在代码中添加 #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方法创建dll的方法已验证ok)的更多相关文章

  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)

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

  4. 浅谈__declspec(dllexport)和__declspec(dllimport)

    __declspec(dllimport)和__declspec(dllexport)经常是成对的,在动态链接库中__declspec(dllexport)导出dll中的成员,__declspec(d ...

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

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

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

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

  7. 从此使用linux系统,但是QQ是必不可少的!!该篇文章方法成功!!!已验证!!!!!

    一开始,我在Ubuntu14.04下安装的QQ版本是WineQQ2013SP6-20140102-Longene, 但后来发现这个版本QQ在linux下问题很多,比如不能用键盘输入密码,QQ表情使用失 ...

  8. DLL进一步讲解:extern "C" __declspec(dllexport)

    一.__declspec(dllexport): 将一个函数声名为导出函数,就是说这个函数要被其他程序调用,即作为DLL的一个对外函数接口. 通常它和extern    "C"   ...

  9. __declspec(dllexport)

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

随机推荐

  1. 谁告诉的你们Python是强类型语言!站出来,保证不打你!

    1. 真的能用隐式类型转换作为强弱类型的判断标准吗?   最近有些学员问我,Python到底是强类型语言,还是弱类型语言.我就直接脱口而出:Python是弱类型语言.没想到有一些学员给我了一些文章,有 ...

  2. composer安装依赖包时,php内存分配不足

    Fatal error: Allowed memory size of 1610612736 bytes exhausted (tried to allocate 4096 bytes) in pha ...

  3. vue项目打包上线发现 360 浏览器不兼容?

    分享链接: 文档:解决vue 和 360 浏览器兼容问题.note链接:http://note.youdao.com/noteshare?id=41914c6dbb4238d765b26d59aa05 ...

  4. photonServer学习之连接数据库

    string connectStr = "server=127.0.0.1;port=3306;database=database;user=root;pwd=root";//连接 ...

  5. python好用的测试库-Nose

    前序: python除了unittest,还有一款更快捷的nose,nose可以说是对unittest的一种简化吧,但是他不需要unittest那种必须有固有的格式,他只需要文件,类名,方法名等含有t ...

  6. 搭建好lnmp后,使用浏览器访问,出现404 Not Found

    出现404 Not Found的原因是nginx指向页面不存在,编辑nginx配置文件,修改nginx指向页面路径 root html; 修改为 root /usr/share/nginx/html; ...

  7. 【Nginx】面试官:给我讲讲Nginx如何实现四层负载均衡?

    写在前面 这次又被问到Nginx四层负载均衡的问题了,别慌,我们一起来细细分析这个看似简单的问题. 如果文章对你有点帮助,请关注 冰河技术 微信公众号,点赞.在看.留言和转发,大家的四连是我持续创作的 ...

  8. 借助Java的JDBC自制“DBMS”管理操作数据库

    package jdbc; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; imp ...

  9. Java单例模式的实现与破坏

    单例模式是一种设计模式,是在整个运行过程中只需要产生一个实例.那么怎样去创建呢,以下提供了几种方案. 一.创建单例对象 懒汉式 public class TestSingleton { // 构造方法 ...

  10. oracle之字符集

    全球化特性与字符集 数据库的全球化特性是数据库发展的必然结果,位于不同地区.不同国家.不用语言而使用同一数据库越来越普遍.Oracle数据库提供了对全球化数据库的支持,消除不同文字.语言环境.历法货币 ...