__declspec是Microsoft VC中专用的关键字,它配合着一些属性可以对标准C/C++进行扩充。__declspec关键字应该出现在声明的前面。

__declspec(dllexport)用于Windows中的动态库中,声明导出函数、类、对象等供外面调用,省略给出.def文件。即将函数、类等声明为导出函数,供其它程序调用,作为动态库的对外接口函数、类等。

.def文件(模块定义文件)是包含一个或多个描述各种DLL属性的Module语句的文本文件。.def文件或__declspec(dllexport)都是将公共符号导入到应用程序或从DLL导出函数。如果不提供__declspec(dllexport)导出DLL函数,则DLL需要提供.def文件。

__declspec(dllimport)用于Windows中,从别的动态库中声明导入函数、类、对象等供本动态库或exe文件使用。当你需要使用DLL中的函数时,往往不需要显示地导入函数,编译器可自动完成。不使用__declspec(dllimport)也能正确编译代码,但使用__declspec(dllimport)使编译器可以生成更好的代码。编译器之所以能够生成更好的代码,是因为它可以确定函数是否存在于DLL中,这使得编译器可以生成跳过间接寻址级别的代码,而这些代码通常会出现在跨DLL边界的函数调用中。声明一个导入函数,是说这个函数是从别的DLL导入。一般用于使用某个DLL的exe中。

In Microsoft,the extended attribute syntax for specifying storage-class information uses the__declspec keyword, which specifies that an instance of a given type is to be stored with a Microsoft-specific storage-class attribute.

Extended attribute grammar supports these Microsoft-specific storage-class attributes:align, allocate, appdomain, code_seg, deprecated, dllexport, dllimport, jitintrinsic, naked, noalias, noinline, noreturn, nothrow, novtable, process,restrict, safebuffers, selectany, and thread. It also supports these COM-object attributes: property and uuid. The code_seg, dllexport, dllimport, naked,noalias, nothrow, property, restrict, selectany, thread, and uuid storage-class attributes are properties only of the declaration of the object or function to which they are applied. The thread attribute affects data and objects only. The naked attribute affects functions only. The dllimport and dllexport attributes affect functions, data, and objects. The property, selectany, and uuid attributes affect COM objects.

The __declspec keywords should be placed at the beginning of a simple declaration. The compiler ignores, without warning, any __declspec keywords placed after * or& and in front of the variable identifier in a declaration. A __declspec attribute specified in the beginning of a user-defined type declaration applies to the variable of that type.

The dllexport and dllimport storage-class attributes are Microsoft-specific extensions to the C and C++ languages. You can use them to export and import functions, data, and objects to or from a DLL. These attributes explicitly define the DLL's interface to its client, which can be the executable file or another DLL. Declaring functions as dllexport eliminates the need for a module-definition(.def) file, at least with respect to the specification of exported functions.The dllexport attribute replaces the __export keyword. If a class is marked declspec(dllexport), any specializations of class templates in the class hierarchy are implicitly marked as declspec(dllexport). This means that class templates are explicitly instantiated and the class's members must be defined.

dllexport of a function exposes the function with its decorated name. For C++ functions,this includes name mangling. For C functions or functions that are declared as extern "C", this includes platform-specific decoration that's based on the calling convention. To export an undecorated name, you can link by using a Module Definition (.def) file that defines the undecorated name in an EXPORTS section.

以下是测试代码:新建一个动态库工程Library,然后在CppBaseTest工程中调用Library的接口:

library.hpp:

#ifndef FBC_LIBRARY_LIBRARY_HPP_
#define FBC_LIBRARY_LIBRARY_HPP_// reference: http://geoffair.net/ms/declspec.htm#ifdef _MSC_VER#ifdef FBC_STATIC#define FBC_API#elif defined FBC_EXPORT#define FBC_API __declspec(dllexport)#else#define FBC_API __declspec(dllimport)#endif
#endif#ifdef __cplusplus
extern "C" {
#endifFBC_API int library_add(int a, int b);
FBC_API int value;#ifdef __cplusplus
}
#endiftemplate<typename T>
class FBC_API Simple {
public:Simple() = default;void Init(T a, T b);T Add() const;private:T a, b;
};#endif // FBC_LIBRARY_LIBRARY_HPP_

library.cpp:

#include "library.hpp"
#include <iostream>
#include <string>FBC_API int library_add(int a, int b)
{value = 11;fprintf(stdout, "File: %s, Function: %s, Line: %d\n", __FILE__, __FUNCTION__, __LINE__);return (a+b);
}template<typename T>
void Simple<T>::Init(T a, T b)
{this->a = a;this->b = b;
}template<typename T>
T Simple<T>::Add() const
{fprintf(stdout, "File: %s, Function: %s, Line: %d\n", __FILE__, __FUNCTION__, __LINE__);return (a + b);
}template class Simple<int>;
template class Simple<std::string>;

test_library.hpp:

#ifndef FBC_CPPBASE_TEST_TEST_LIBRARY_HPP_
#define FBC_CPPBASE_TEST_TEST_LIBRARY_HPP_#include <library.hpp>namespace test_library_ {#ifdef __cplusplusextern "C" {
#endif__declspec(dllimport) int library_add(int, int);
__declspec(dllimport) int value;#ifdef __cplusplus}
#endifint test_library_1();
int test_library_2();} // namespace test_library_#endif // FBC_CPPBASE_TEST_TEST_LIBRARY_HPP_

test_library.cpp:

#include "test_library.hpp"
#include <iostream>
#include <string>#include <library.hpp>namespace test_library_ {int test_library_1()
{int a{ 4 }, b{ 5 }, c{ 0 };c = library_add(a, b);fprintf(stdout, "%d + %d = %d\n", a, b, c);fprintf(stdout, "value: %d\n", value);return 0;
}int test_library_2()
{Simple<int> simple1;int a{ 4 }, b{ 5 }, c{ 0 };simple1.Init(a, b);c = simple1.Add();fprintf(stdout, "%d + %d = %d\n", a, b, c);Simple<std::string> simple2;std::string str1{ "csdn blog: " }, str2{ "http://blog.csdn.net/fengbingchun" }, str3;simple2.Init(str1, str2);str3 = simple2.Add();fprintf(stdout, "contents: %s\n", str3.c_str());return 0;
}} // namespace test_library_

GitHub: https://github.com/fengbingchun/Messy_Test

Windows C++中__declspec(dllexport)的使用相关推荐

  1. Windows DLL编程中的导入导出:__declspec(dllimport) ,__declspec(dllexport) ,

    在Windows DLL编程时,可使用__declspec(dllimport)关键字导入函数或者变量. 函数的导入 当你需要使用DLL中的函数时,往往不需要显示地导入函数,编译器可自动完成.但如果你 ...

  2. OpenCV中# define CV_EXPORTS __declspec(dllexport)的含义

    # define CV_EXPORTS __declspec(dllexport) 问题出自: class CV_EXPORTS Mat { ................... }; __decl ...

  3. (转)__declspec(dllimport)和__declspec(dllexport)的区别,以及有关c/c++调用约定

    DLL可以使用两种方法将公共符号导入到应用程序中或从 DLL 导出函数: 生成 DLL 时使用模块定义 (.DEF) 文件.  在主应用程序的函数定义中使用 __declspec(dllimport) ...

  4. 【转】extern “C“以及__declspec(dllexport) 讲解和def文件dll导出方法

    转自:https://blog.csdn.net/qing666888/article/details/41135245 一,__ declspec(dllexport): 将一个函数声名为导出函数, ...

  5. extern C __declspec(dllexport) __declspec(dllimport) 和 def

    前面的extern "C"  __declspec(dllexport)  __declspec(dllimport)都是用于函数或者变量,甚至类的声明的(可以把extern &q ...

  6. c++ 中__declspec 的用法

    语法说明: __declspec ( extended-decl-modifier-seq ) 扩展修饰符: 1:align(#)     用__declspec(align(#))精确控制用户自定数 ...

  7. 【转】extern “C“和__declspec(dllexport)以及__declspec(dllimport) 和def的简单解析

    转自:https://blog.csdn.net/xupan_jsj/article/details/9028759 前面的extern "C"  __declspec(dllex ...

  8. 从static变量导出问题解析 __declspec(dllexport) 和 __declspec(dllimport)的作用

    这段时间要把tinyxml从静态库弄成动态库,要用到__declspec(dllexport)和__declspec(dllimport)来导出dll和lib文件.终于弄明白了export和impor ...

  9. __declspec(dllexport)、__declspec(dllimport)详解

    在Visual studio中新建DLL项目时编译器会自动生成下面这样的宏定义: #ifdef DLL_EXPORTS #define DLL_API __declspec(dllexport) #e ...

最新文章

  1. android servlet 登陆,Android Studio+Servlet+MySql实现登录注册
  2. 2020自然指数重磅发布:中科院第一,中国科大、北大跻身前十
  3. 电信在线防杀毒墙,到底是不是流氓软件
  4. 厚积薄发,丰富的公用类库积累,助你高效进行系统开发(2)(转)
  5. 【Linux】一步一步学Linux——fgrep命令(了解)(51)
  6. git idea 图形化_Git大全,你所需要的Git资料都在这里
  7. C#LeetCode刷题之#205-同构字符串(Isomorphic Strings)
  8. hssfcell判断文本类型_ICML 2020 | 显式引入对分类标签的描述,如何提高文本分类的效果?...
  9. oracle的文件管理ofm,oracle 文件管理功能
  10. OpenMP对于嵌套循环应该添加多少个parallel for
  11. 查看 java heapspace_Java heap space 问题查找
  12. AS3文本框的操作,为密码框添加按钮
  13. 后台管理软件测试用例,如何进行测试用例管理?
  14. Android开发两年,我要跳槽去阿里巴巴了,做个阶段总结,flutterrow高度对齐
  15. 2017 robotart x86_RobotArt:机器人离线编程仿真软件领航者
  16. 老鹰-第一次Python笔记
  17. xp下载的java8_windows xp下安装java8(jdk8) 看完就明白
  18. subplots用法总结
  19. postgrest 简单使用
  20. Python番外篇:电脑读心术程序 快给你的同事朋友玩一玩

热门文章

  1. 基于openCV的项目实战1:信用卡数字识别
  2. C:内存中供用户使用的存储空间
  3. 力扣(LeetCode)刷题,简单题(第5期)
  4. 优达学城《DeepLearning》2-2:迁移学习
  5. 【合并单元格】纵向合并单元格之前对数组处理【针对饿了么element的table的span-method合并行或列的计算方法】
  6. 在Ubuntu 14.04 64bit上使用pycURL模块示例
  7. Blender数字雕刻终极指南学习教程
  8. 使用Vuforia Unity构建增强现实应用
  9. Linux 下 进程运行时内部函数耗时的统计 工具:pstack,strace,perf trace,systemtap
  10. Rocksdb DeleteRange实现原理