参考自:http://bbs.csdn.net/topics/330169671

__declspec(dllexport):导出符号,也就是定义需要导出函数的dll中给导出函数的函数声明前面加上导出符号,表示该方法可以导出给其他DLL或者exe使用;

__declspec(dllimport)导入符号,也就是在使用该函数的DLL或者exe中需要在该函数的函数声明前面加上该符号,表示该函数方法是从其他库导入的。

我们编写一个DLL库一般都是用来给其他DLL或者exe程序调用的。当我们编写DLL库时,要想把该库中的函数导出来给其他DLL或者exe使用,

一般有两种方式:一是在声明该函数的声明函数前面加上导出符号__declspec(dllexport);二是在.def文件中写上导出函数。

因为导出函数的头文件一般既要给导出DLL使用,又要给调用该导出DLL函数的DLL或者EXE使用。而导出DLL库给其他DLL或者EXE程序使用的时候,函数是相当于导入该DLL或者EXE的,

所以其头文件的声明中的__declspec(dllexport)导出符号改成__declspec(dllimport)导入符号。

为了方便使用和维护同一分头文件,所以在导出函数的头文件中加上

#ifdef _EXPORTING
#define CLASS_DECLSPEC __declspec(dllexport)
#else
#define CLASS_DECLSPEC __declspec(dllimport)
#endif

这段代码。

我们在该导出DLL的编译选项定义中定义宏 #define _EXPORTING,而在调用该导出函数DLL的其他DLL或者exe的编译选项中不定义宏_EXPORTING。

那么导出头文件和导入头文件就可以只维持一份头文件了,有利于维护。

关于导入头文件中要把__declspec(dllexport)改成 __declspec(dllimport)问题

一、关于 __declspec(dllimport)我刚才找了一下,有人写过相关的文章,大意是说,不用这个也链接器也能工作,不过用它更好。原文是说:
不使用 __declspec(dllimport) 也能正确编译代码,但使用 __declspec(dllimport) 使编译器可以生成更好的代码。编译器之所以能够生成更好的代码,是因为它可以确定函数是否存在于 DLL 中,这使得编译器可以生成跳过间接寻址级别的代码,而这些代码通常会出现在跨 DLL 边界的函数调用中。但是,必须使用 __declspec(dllimport) 才能导入 DLL 中使用的变量。

隐式使用dll时,不加__declspec(dllimport)完全可以,使用上没什么区别,只是在生成的二进制代码上稍微有点效率损失。

1、不加__declspec(dllimport)时,在使用dll中的函数时,编译器并不能区别这是个普通函数,还是从其它dll里导入的函数,所以其生成的代码如下:
call 地址1
地址1:
   jmp  实际函数地址

2、有__declspec(dllimport)时,编译器知道这是要从外部dll导入的函数,从而在生成的exe的输入表里留有该项,以便在运行exe,PE载入器加载exe时对输入地址表IAT进行填写,这样生成的代码如下:
call dword ptr[输入表里哪项对应的内存地址] (注意:现在就不需要jmp stub了)

二、导入全局、静态或者类成员变量需要__declspec(dllimport)。

#define DllImport   __declspec(dllimport)

DllImport int  j;

__declspec(dllexport)是用于避免需要自己写DEF文件的。编译器会为被__declspec(dllexport)修饰的函数自动添加一个导出函数入口。如果你在其他模块中包含__declspec(dllexport)的头文件,这些项目的导出表中也会生成一个同名导出函数。

__declspec(dllimport)与__declspec(dllexport)作用总结的更多相关文章

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

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

  2. __declspec(dllimport)的作用

    是时候总结一下__declspec(dllimport)的作用了.可能有人会问:__declspec(dllimport)和__declspec(dllexport)是一对的,在动态链接库中__dec ...

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

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

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

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

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

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

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

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

  7. __declspec(dllexport) & __declspec(dllimport)

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

  8. 动态链接库(dll) __declspec(dllimport) __declspec(dllexport)

    一. __declspec(dllexport) Microsoft 在 Visual C++ 的 16 位编译器版本中引入了 __export,使编译器得以自动生成导出名并将它们放到一个 .lib ...

  9. 【转载】extern "C" __declspec(dllexport) __declspec(dllimport) 和 def

    转自:http://www.cppblog.com/FateNo13/archive/2009/08/03/92052.html 前面的extern "C"  __declspec ...

随机推荐

  1. C艹 指针和const的关系和注意事项(非常有意思)

    有两种不同的形式将const关键字指向指针. 第一种:让指针指向一个常量对象 const float g_moon = 1.63; float * pm = &g_moon; // 不允许 n ...

  2. SpagoBI 论坛

    http://www.spagoworld.org/jforum/forums/list.page

  3. android 8 wifi 信号等级

    wifi信号等级 /frameworks/base/wifi/java/android/net/wifi/wifimanager.java calculateSignalLevel为计算信号等级函数, ...

  4. qualcomm 查看 wifi 配置生效

    iwpriv wlan0 getConfig 然后收集dmesg, 或者执行这条命令: dmesg | grep gEnableBmps

  5. html常用对照表

    常用对照表:http://tool.oschina.net/commons

  6. bioerl 获取gi号

    代码示例: use Bio::DB::EUtilities; my @ids = qw(CAB02640 EAS10332 YP_250808 NP_623143 P41007); my $facto ...

  7. 安装oh my zsh和git插件

    http://macshuo.com/?p=676   --安装oh my zsh http://www.jianshu.com/p/9189eac3e52d https://github.com/r ...

  8. Vi编辑器修改文件.bash_profile可解决backspace出现乱码问题,rlwrap 的安装。

    Vi编辑器修改文件.bash_profile可解决backspace出现乱码问题 使用SecureCRT或是pietty_ch连接到一台安装有Oracle DB 10g的RHEL4.2的机器,linu ...

  9. ubuntu 12.04 右上角的网络连接图标突然消失不见

    某天Ubuntu右上角的网络连接图标突然消失不见了,右击panel -> add to panel -> Notification Area 也不管用,最关键的是上不了网了.可以在Netw ...

  10. node.js和socket.io实现im

    im——Instant Messaging 即时通讯 基本技术原理 (1)通过IM服务器登陆或注销 (2)用户A通过列表找到B,用户B获得消息并与之交谈 (3)通过IM服务器指引建立与B单独的通讯通道 ...