`
happmaoo
  • 浏览: 4333417 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

总结一下__declspec(dllimport)的作用

阅读更多

作者:朱金灿
来源:http://blog.csdn.net/clever101/


是时候总结一下__declspec(dllimport)的作用了。可能有人会问:__declspec(dllimport)和__declspec(dllexport)是一对的,在动态链接库中__declspec(dllexport)管导出,__declspec(dllimport)管导出,就像一个国家一样,有出口也有进口,有什么难理解的呢?这是一种很自然的思路,开始我也是这样理解。


但是在两年前的一个项目中,我发现不用__declspec(dllimport)似乎也可以。比如现在我新建一个使用共享MFC DLL的规则DLL工程:DllDlg。然后我新建两个文件:DllApi.h和DllApi.cpp。DllApi.h作为接口文 件,DllApi.cpp作为实现文件。


接着在DllApi.h声明一个函数:


在DllApi.cpp写这个函数的实现:



这样外部的应用程序或dll就能调用HelloWorld函数。这里要特别提醒的是:有些网友说要把DllApi.h中的__declspec(dllexport) void HelloWorld();改为__declspec(dllimport) void HelloWorld();才能提供给外部调用,实际上这并不需要,这个我已经测试过。从那时我就产生一个疑问:照这样,像类似下面的:


是不是就只剩下一种作用:让外部调用者看得更自然些,知道哪些接口是自己工程需要导入的?__declspec(dllimport)是不是一点实际作用都没有呢?这个疑问一直盘旋在我的脑海。直到最近,我在CSDN论坛上发了一个帖子:


__declspec(dllimport) 的作用到底在哪里呢?

总结了各位大虾的发言,特得出如下结论:

1. 在导入动态链接库中的全局变量方面起作用:
使用类似


可以更好地导出dll中的全局变量,比如按照的宏,可以在dll中这样导出全局变量:



然后在调用程序这样导入:



当然也可以使用extern关键字,比如在dll中这样导出全局变量:



然后在调用程序这样导入:



但据说使用__declspec(dllimport)更有效。


2. __declspec(dllimport)的作用主要体现在导出类的静态成员方面,
比如在动态链接库中定义这样一个导出类:



照上面这样声明,外部虽然可以使用CBtt类,但不能使用CBtt类的GetValue函数,一使用就会出现无法解析的外部符号 "public: static int CBtt::m_nValue" (?m_nValue@CBtt@@2HA)。只有如下声明才能使用CBtt类的GetValue函数:




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


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

call 地址1

地址1:
jmp 实际函数地址


b、有 __declspec(dllimport)时,编译器知道这是要从外部dll导入的函数,从而在生成的exe的输入表里留有该项,以便在运行 exe,PE载入器加载exe时对输入地址表IAT进行填写,这样生成的代码如下:

call dword ptr[输入表里哪项对应的内存地址] (注意:现在就不需要jmp stub了)。这里
有兴趣的朋友可以参看《编译原理》和 PE文件格式。


4.使用__declspec(dllimport)体现了语言的一种对称美,比如虽然!true就是表示false,但是我们还是需要false这个关键字,这里体现了一种对称美。

在此特别感谢CSDN的众位大侠:superdiablo、wltg2001、ccpaishi、jszj、WizardK、hurryboylqs、jingzhongrong、jameshooo、glacier3d、winnuke、starnight1981、laiyiling、yang79tao、ForestDB、zhouzhipen、lxlsymbome、Beyond_cn。


参考文献:


1. __declspec(dllimport) 到底有什么用?


































分享到:
评论

相关推荐

    __declspec(dllexport)和__declspec(dllimport)的区别是什么

    __declspec(dllexport)和__declspec(dllimport)的区别是什么

    caffe分类器动态库编译

    动态库编译好了,提供dll,lib,.h.以及测试代码、只需要自己的训练的分类器,网络结构均值,类别就可以试用了

    declspec(dllexport)与_declspec(dllimport)的区别

    declspec(dllexport)与_declspec(dllimport)的区别

    c 调用Python

    简单的Hello world 以后不断更新 慢慢的来, ^_^

    jemalloc库windows版本

    jemalloc库是用来替代系统自带的malloc和...extern "C" __declspec(dllimport) void* je_malloc(size_t size); extern "C" __declspec(dllimport) void je_free(void *ptr); #pragma comment (lib, "jemalloc.lib")

    使用extern "C"改善显式调用dll的例子 (c++)

    使用extern "C"改善显式调用dll的例子

    【Visual C++】Code_Note_2

    博文的配套源码 《【 Visual C++】游戏开发笔记之二——最简单的directx,vc窗口的编写 》 ,原文地址为... 源码编译环境为vs2010. ... 希望能和大家一起交流,共同学习,共同进步。

    CComps安装

    extern "C" int __declspec(dllimport) __stdcall LoadBMP(char *FileName,char *PicName, Graphics::TBitmap *MyBMP); extern "C" int __declspec(dllimport) __stdcall LoadBMPData(char *FileName,char *PicName,...

    C++ 编写DLL文件给易语言调用方法

    摸索了两天了,终于解决了所有问题,在此跟大家分享。 需要三个文件,dll_demo.h、dll_demo.cpp、dll_dome.def ...#define DLL_DEMO extern "C" __declspec(dllimport) #endif DLL_DEMO int __stdcall Add(int a, int

    window 串口通讯 测试通过

    #define ZRD_Com __declspec(dllimport) #endif // Receive Data Function typedef void(_stdcall *OnReceive)(const char* Result,int count); // OpenCom // Return Com Handle ID, if fail 0 ZRD_...

    使用HOOK屏蔽系统快捷键

    1.修改TaskKeyHook.h中的宏定义 #define DLLIMPORT extern "C" __declspec(dllimport) _stdcall 修改TaskKeyHook.cpp的宏定义 #define DLLEXPORT extern "C" __declspec(dllexport) 2.重新编译生成TaskKeyHook.DLL 3...

    C++ 中动态链接库–导入和导出的实例详解

    __declspec(dllexport)和__declspec(dllimport): __declspec(dllexport):编译器看到一个变量、函数或者C++类被它修饰,那么它就知道应该在生成的DLL 模块中导出该变量、函数或C++类。 __declspec(dllimport):...

    Python调用C/C++动态链接库的方法详解

    本文以实例讲解了Python调用C/C++ DLL动态链接库的方法,具体...#define HELLO_API __declspec(dllimport) #endif extern "C" { HELLO_API int IntAdd(int , int); } CPP文件: //hello.cpp #define EXPORT_HELLO

    运动会分数统计 C++

    #define _CRTIMP __declspec(dllimport) #else /* ndef _DLL */ #define _CRTIMP #endif /* _DLL */ #endif /* _CRTIMP */ /* Define _CRTAPI1 (for compatibility with the NT SDK) */ #ifndef _CRTAPI1 #if _MSC...

    自己写的dll的简介

    对于DLL的用户来讲,类声明就需要用另外一个关键字__declspec(dllimport)(此关键字对于类和函数而言并非必须,但对于变量而言则是必须的)。所以通常我们会定义一个宏来包装之,比如 #ifdef MYDLL_EXPORTS # ...

    链接库知识锦集

    __declspec(dlldexport)/__declspec(dllimport)含义及使用 __stdcall含义及使用 各种类型dll的含义及使用和区别。 ----------------------------------------------------------------- _stdcall的作用: 这是一种...

    C++生成dll和调用dll的方法实例

    #ifdef BUILD_XXX_DLL#define EXPORT __declspec(dllexport)#else#define EXPORT __declspec(dllimport)#endif extern “C”{EXPORT void example(void);… …} xxx.cpp内容如下: #define BUILD_XXX_DLL#include ...

    解析VC中创建DLL,导出全局变量,函数和类的深入分析

    函数和类的头文件MathLib.h: 代码如下: //MathLib.h #pragma once #ifdef MATHLIB_EXPORT #define MATHLIBAPI __declspec(dllexport) #else #define MATHLIBAPI __declspec(dllimport) #endif //mac

    VS2015如何创建一个DLL.docx

    一步一步学习Visual Studio 2015 Community创建DLL,整体来看和Visual Studio 6.0是一样的。只是IDE的环境变了,本例程是...#define VSAPI _declspec(dllimport) #endif #define EVSAPI extern "C" VSAPI #endif

Global site tag (gtag.js) - Google Analytics