關於編寫c++動態庫常用的定義
阿新 • • 發佈:2020-09-16
1. 關於
- 1.1 最近一段時間,寫了不少動態庫,慢慢的也積累了東西。
- 1.2 之前一直做Windows的動態庫,沒有做過Linux和OS X的動態庫,太缺乏經驗了: 程式碼缺乏 編譯器支援的判斷、缺乏c++版本判斷、缺乏作業系統的判斷.... 總之,導致了很多問題。
2. Unicode和ANSI
這個,特別是 call Windows API 很明顯,一個Windows API函式提供了 Unicode和ANSI的支援。新增下面的巨集支援兩種編碼:
// to // c/c++ run time library #ifdef _UNICODE #ifndef UNICODE #define UNICODE #endif #endif // windows #ifdef UNICODE #ifndef _UNICODE #define _UNICODE #endif #endif
一個例子,演示需要呼叫函式CreateFile,它有2個版本:CreateFileA 和 CreateFileW,其第一個引數是裝置的名字,可以這樣寫:
TCHAR *tc_com_name = nullptr; #ifdef UNICODE std::wstring wstr = str2wstr(spp._name); tc_com_name = const_cast<TCHAR *>(wstr.c_str()); #else tc_com_name = const_cast<TCHAR*>(spp._name.c_str()); #endif // !UNICODE
呼叫函式CreateFile:CreateFile( tc_com_name, ...)
就好啦。
3. __cplusplus
通常使用這個巨集判斷c++的版本,但是, Visual Studio X (X = 2003, 2005, 2008 , 2010... 下面簡稱VS)編譯器中,這個預設值一直都是:199711L。官網也說了,目前僅支援VS2017(version 15.7)及以上版本可以新增命令修改, 具體的可以看這裡。
使用__cplusplus判斷c++版本示例:
#if __cplusplus >= 201103L
#define has_cxx_11
#endif //
4. 動態庫匯出符
根據作業系統的不同,設定對應的巨集(一個例子)
// to definite an export flag
#if defined(_WIN32) || defined(_WIN64) || defined(WIN32)
//----------------------------------------------------------------------
#ifndef _lib_sp_api_
#define _lib_sp_api_ __declspec(dllexport)
#else
#define _lib_sp_api_ __declspec(dllimport)
#endif /// !_lib_pipe_api_
#elif defined(_unix_) || defined(_linux_) || defined(_unix) || defined(_linux) || #elif defined(__APPLE__)
//----------------------------------------------------------------------
#ifndef _lib_sp_api_
#define _lib_sp_api_ __attribute__((visibility ("default")))
#endif /// !_lib_pipe_api_
#endif /// !
5. 編譯器判斷
可能你需要根據編譯器的不同執行某些程式碼,下面的程式碼可以幫到你,一個例子
#if defined(__clang__) || defined(__GNUC__)
// clang or gcc(++)
#elif defined(_MSC_VER) // use vs compiler
#if 1900 <= _MSC_VER // 1900 = vs2015
#ifndef has_cxx_11
#define has_cxx_11
#endif //
#endif
#endif
6. 作業系統的判斷
可能你還需要對作業系統的判斷,比如編寫串列埠通訊時,需要call系統api完成相關操作,下面的程式碼可以幫到你。 一個例子:
#if defined(_WIN32) || defined(_WIN64)
# ifndef os_is_win
#define os_is_win
#else
#endif /// os_is_win
#elif defined(_linux) || defined(_linux_) || defined() || defined (_unix_)
# ifndef os_is_linux
#define os_is_linux
#else
#endif /// os_is_linux
#elif defined(__APPLE__)
#ifndef os_is_apple
#define os_is_apple
#else
#endif /// os_is_apple
#endif //