Windows C++中__declspec(dllexport)的使用
__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)的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CUDA Samples: Image
- 下一篇: Python实现决策树(Decision