1. 程式人生 > 實用技巧 >關於編寫c++動態庫常用的定義

關於編寫c++動態庫常用的定義

1. 關於

  • 1.1 最近一段時間,寫了不少動態庫,慢慢的也積累了東西。
  • 1.2 之前一直做Windows的動態庫,沒有做過Linux和OS X的動態庫,太缺乏經驗了: 程式碼缺乏 編譯器支援的判斷、缺乏c++版本判斷、缺乏作業系統的判斷.... 總之,導致了很多問題。

2. Unicode和ANSI

這個,特別是 call Windows API 很明顯,一個Windows API函式提供了 UnicodeANSI的支援。新增下面的巨集支援兩種編碼:

// 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個版本:CreateFileACreateFileW,其第一個引數是裝置的名字,可以這樣寫:

	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

呼叫函式CreateFileCreateFile( 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 //