关于编写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 // 

7.附完整版

copy即可使用

// c/c++ run time library
#ifdef _UNICODE
	#ifndef UNICODE
		#define UNICODE
	#endif
#endif

// windows 
#ifdef UNICODE
	#ifndef _UNICODE
		#define _UNICODE
	#endif
#endif



// cpp_version to check if it suppports c++11
//---------------------------------------------------------------------------------------------
#if __cplusplus >= 201103L
	#define use_cpp_11 
#endif // ! __cplusplus >= 201103L


// compiler
//---------------------------------------------------------------------------------------------
#if defined(__clang__) || defined(__GNUC__)
	#define compiler_is_clang
// clang or gcc(++)
#elif defined(_MSC_VER)		// use vs compiler

	#ifndef compiler_is_vs
		#define compiler_is_vs
	#endif //! compiler_is_vs
//--------------------------------------------

	#if 1900 <= _MSC_VER	// 1900 = vs2015

		#ifndef use_cpp_11
			#define use_cpp_11
		#endif // 

	#endif


#endif //! defined(__clang__) || defined(__GNUC__)


// os
//---------------------------------------------------------------------------------------------
#if defined(_WIN32) || defined(_WIN64)

	#ifndef os_is_win
		#define os_is_win 
	#else
	#endif // os_is_win 

#elif defined(_linux) || defined(_linux_) || defined(__linux) || defined (_unix_)

	#ifndef os_is_linux
		#define os_is_linux
	#else
	#endif /// os_is_linux 

#elif defined(__APPLE__)
	#ifndef os_is_osx
		#define os_is_osx
	#else
	#endif /// os_is_osx 

#endif // !defined(_linux) || defined(_linux_) || defined(__linux) || defined (_unix_)



// -----------------------------------------------------------------------------------------
#if defined(os_is_win)

	#ifndef _oct_udp_api_export_export_
		#define _lib_udp_api_export_		__declspec(dllexport)
	#else
		#define _lib_udp_api_export_		__declspec(dllimport)
	#endif //! _oct_udp_api_export_export_

// -----------------------------------------------------------------------------------------
#elif defined(os_is_linux) || defined(os_is_osx)

	#ifndef _oct_udp_api_export_export_
		#define _lib_udp_api_export_		__attribute__((visibility("default")))
	//#define _oct_udp_api_export_		__attribute__ ((visibility("default")))
	#endif // !_oct_udp_api_export_export_

#endif // !os_is_win

posted @ 2020-09-16 16:49  mohist  阅读(667)  评论(0编辑  收藏  举报