在笔者从事嵌入式软件开发的这六七年时间里,因为涉及到多块硬件平台以及多种系统平台(如 linux,android,windows,freeRTOS等)。还有gcc和visual studio以及keil等构建工具,这些对基本数据类型的定义,以及编译动态库时对接口导出方式等存在大小不一的差异,所以,为了方便进行跨平台middleware软件的开发,就定义了一下的三个通用公共头文件。
注意:在这些头文件中,定义的数据类型或宏都是以 G 开头的,这里的G,就是General的首字母(通用,常规)
此头文件主要定义基础数据类型,API接口导出关键字(以宏模拟),inline关键字兼容宏(因visual studio中c语言是不支持inline关键字的),其具体头文件如下:
/*****************************************************************************
* Name:general_type.h
*
* Purpose: standard header,and unified data type define
*
* Note: 'G' in macro and data type indicate 'general'
*
* Version: 0.3
*
*
*****************************************************************************/
#ifndef __GENERAL_TYPE_H__
#define __GENERAL_TYPE_H__
#include
#include
/**
* general type define and some keyword Compatible.
* The user can define the following macros in the build script to
* control library's behavior. If the user doesn't define a macro
* in this list, general_type.h will define it.
* DLL_EXPORT - Define to 1 when compiling library itself
* as a shared library.
* G_FS_BITS - Define to 64 when need to operation large file.
*
*/
/***************************************************************************
* general data type define.
***************************************************************************/
typedef void* GPHD; //general instance handle type
typedef void* GADR; //general address type
typedef void* GPTR; //general pointer type
typedef char* GSTR; //general string type
typedef char GCHR; //general character type
typedef wchar_t GWCH; //general width character type.
//general signed integer type
typedef char GS08; //8 bits
typedef short GS16; //16 bits
typedef int GS32; //32 bits
typedef long long GS64; //64 bits
//general unsigned integer type
typedef unsigned char GU08; //8 bits
typedef unsigned short GU16; //16 bits
typedef unsigned int GU32; //32 bits
typedef unsigned long long GU64; //64 bits
//general float type
typedef float GFLT;
typedef double GDBL;
//boolean type declaration
typedef GU32 GBOL;
#ifndef GTRUE /** boolean true */
#define GTRUE 1
#endif
#ifndef GFALSE /** boolean false */
#define GFALSE 0
#endif
/***************************************************************************
* general data type limit(maximum and minmum) value define.
***************************************************************************/
#define GS08_MIN (-127 - 1)
#define GS16_MIN (-32767 - 1)
#define GS32_MIN (-2147483647 - 1)
#define GS64_MIN (-9223372036854775807LL - 1)
#define GS08_MAX 127
#define GS16_MAX 32767
#define GS32_MAX 2147483647
#define GS64_MAX 9223372036854775807LL
#define GU08_MAX 0xff
#define GU16_MAX 0xffff
#define GU32_MAX 0xffffffff
#define GU64_MAX 0xffffffffffffffffULL
/***************************************************************************
* define extern "C" macro.
***************************************************************************/
#ifdef __cplusplus
#define G_EXTERN_C extern "C"
#else
#define G_EXTERN_C
#endif
/***************************************************************************
* macro define for specfial toolchain.
***************************************************************************/
#if defined(__GNUC__) /** !!!for gcc */
#define G_GCC_VERSION(maj,min) \
((__GNUC__ > (maj)) || (__GNUC__ == (maj) && __GNUC_MINOR__ >= (min)))
/** define API export macro */
#if G_GCC_VERSION(4,0) //for gcc(version >= 4.0)
#define G_DLL_EXPORT __attribute__((visibility("default")))
#else
#define G_DLL_EXPORT
#endif
/** define operation system type */
#if defined(__linux__)
#if defined(__ANDROID__)
#define G_OS_ANDROID
#else
#define G_OS_LINUX
#endif
#endif
/** define operation system bit depth */
#if (__SIZEOF_POINTER__ == 4) //pointer size is 4 byte(treat as 32bits os)
#define G_OS_BITS 32
#elif (__SIZEOF_POINTER__ == 8)//pointer size is 8 byte(treat as 64bits os)
#define G_OS_BITS 64
#else
#error "!!unknown os bit depth!!"
#endif
#elif defined(_MSC_VER) /** !!!for visual studio */
/** compat the keyword 'inline' */
#if (_MSC_VER > 1200) && !defined (__cplusplus)
#define inline _inline /** to compat keyword 'inline' */
#endif
/** auto define API export macro */
#if !defined(DLL_EXPORT) && defined(_WINDLL) //todo,process _USRDLL,_AFXDLL
#define DLL_EXPORT
#endif
#if defined (DLL_EXPORT)
#define G_DLL_EXPORT __declspec(dllexport)
#else
#define G_DLL_EXPORT
#endif
/** operation system type and bit depth define */
#if defined(_WIN64)
#define G_OS_BITS 64
#define G_OS_WINDOWS
#elif defined(_WIN32)
#define G_OS_BITS 32
#define G_OS_WINDOWS
#else
#error "unknown system type and bit depth, compile with MSVC "
#endif
#else /** !!!for unknown toolchain */
///
#error "!!unspport this toolchain at now!!"
#endif /** !!! end of toolchin define */
/***************************************************************************
* default macro define.
***************************************************************************/
/** the flag of file operation */
#if !defined(G_FS_BITS)
/**
* default enable large file operation, here just indicate os API,
* whether support large file, Decision by file system.
*/
#define G_FS_BITS 64
#endif
/***************************************************************************
* common macro define.
***************************************************************************/
/** general api decorate macro */
#define G_API G_EXTERN_C G_DLL_EXPORT
/** general class decorate macro*/
#define G_CLASS G_DLL_EXPORT
/** path separator define */
#if defined(G_OS_WINDOWS)
#define PATH_SEPARATOR '\\'
#elif defined(G_OS_LINUX) || defined(G_OS_ANDROID)
#define PATH_SEPARATOR '/'
#else
#error "unknown system type"
#endif
/***************************************************************************
* some special data type define.
***************************************************************************/
#endif //end of __GENERAL_TYPE_H__
通用宏头文件中,主要定义的是操作,比较,读写,断言等等。
/*****************************************************************************
* Name:general_macro.h
*
* Purpose:standard header,and unified mcaro define
*
* Warning:
* these macro cann't have any ++, -- in parameter.
*
*****************************************************************************/
#ifndef __GENERAL_MACRO_H__
#define __GENERAL_MACRO_H__
#include
#include "general_type.h"
/***************************************************************************
*math macro define
***************************************************************************/
#define GABS(a) (((a) > 0) ? (a) : -(a))
#define GMIN(a, b) ((a) < (b) ? (a) : (b))
#define GMAX(a, b) ((a) > (b) ? (a) : (b))
/**make sure the range of v, between 'min' and 'max' */
#define GCLIP(v, min, max) GMIN(GMAX(v, min), max)
//fourcc macro define
#define GFCC(a, b, c, d) (((GU32)a) | (((GU32)b) << 8) | (((GU32)c) << 16) | (((GU32)d) << 24))
/***************************************************************************
*bytes operation macro define
***************************************************************************/
// read 2 bytes data by big endian
#define GRB2(a) ((GU16)((((GU08*)(a))[0] << 8) | ((GU08*)(a))[1]))
// read 3 bytes data by big endian
#define GRB3(a) ((GU32)((((GU08*)(a))[0] << 16) | (((GU08*)(a))[1] << 8) | ((GU08*)(a))[2]))
// read 4 bytes data by big endian
#define GRB4(a) ((GU32)((((GU08*)(a))[0] << 24) | (((GU08*)(a))[1] << 16) | \
(((GU08*)(a))[2] << 8) | ((GU08*)(a))[3]))
// read 8 bytes data by big endian
#define GRB8(a) ((((GU64)((GU08*)(a))[0]) << 56) | (((GU64)((GU08*)(a))[1]) << 48) | \
(((GU64)((GU08*)(a))[2]) << 40) | (((GU64)((GU08*)(a))[3]) << 32) | \
(((GU64)((GU08*)(a))[4]) << 24) | (((GU64)((GU08*)(a))[5]) << 16) | \
(((GU64)((GU08*)(a))[6]) << 8) | (GU64)(((GU08*)(a))[7]))
// read 2 bytes data by little endian
#define GRL2(a) ((GU16)(((GU08*)(a))[0] | (((GU08*)(a))[1] << 8)))
// read 3 bytes data by little endian
#define GRL3(a) ((GU32)(((GU08*)(a))[0] | (((GU08*)(a))[1] << 8) | (((GU08*)(a))[2] << 16)))
// read 4 bytes data by little endian
#define GRL4(a) ((GU32)(((GU08*)(a))[0] | (((GU08*)(a))[1] << 8) | \
(((GU08*)(a))[2] << 16) | (((GU08*)(a))[3] << 24)))
// read 8 bytes data by little endian
#define GRL8(a) (((GU64)((GU08*)(a))[0]) | (((GU64)((GU08*)(a))[1]) << 8) | \
(((GU64)((GU08*)(a))[2]) << 16) | (((GU64)((GU08*)(a))[3]) << 24) | \
(((GU64)((GU08*)(a))[4]) << 32) | (((GU64)((GU08*)(a))[5]) << 40) | \
(((GU64)((GU08*)(a))[6]) << 48) | (((GU64)((GU08*)(a))[7]) << 56))
// write 2 bytes data as big endian
#define GWB2(a, b) do{((GU08*)(a))[0] = (b) >> 8;((GU08*)(a))[1] = (b);}while(0)
// write 4 bytes data as big endian
#define GWB4(a, b) do{((GU08*)(a))[0] = (b >> 24);((GU08*)(a))[1] = (b >> 16); \
((GU08*)(a))[2] = (b >> 8);((GU08*)(a))[3] = (b);}while(0)
// write 2 bytes data as little endian
#define GWL2(a, b) do{((GU08*)(a))[0] = (b);((GU08*)(a))[1] = (b >> 8);}while(0)
// write 4 bytes data as little endian
#define GWL4(a, b) do{((GU08*)(a))[0] = (b);((GU08*)(a))[1] = (b >> 8); \
((GU08*)(a))[2] = (b >> 16);((GU08*)(a))[3] = (b >> 24);}while(0)
// swap 2 bytes integer
#define GSWAP2(a) ((GU16)((((a) & 0xff00) >> 8) | (((a) & 0xff) << 8)))
// swap 4 bytes integer
#define GSWAP4(a) ((((a) & 0xff) << 24) | (((a) & 0xff00) << 8) | \
(((a) >> 8) & 0xff00) | (((a) >> 24) & 0xff))
//write little endian data to a ptr unit in bytes
#define GPWL1(p, b) (*(p)++ = (GU08)(b))
#define GPWL2(p, var) do{*(p)++ = (GU08)((var)>>0);*(p)++ = (GU08)((var)>>8);} while(0)
#define GPWL4(p, var) do{*(p)++ = (GU08)((var)>>0);*(p)++ = (GU08)((var)>>8); \
*(p)++ = (GU08)((var)>>16);*(p)++ = (GU08)((var)>>24);}while(0)
//write big endian data to a ptr unit in bytes
#define GPWB1(p, b) (*(p)++ = (GU08)(b))
#define GPWB2(p, var) do{*(p)++ = (GU08)((var)>>8);*(p)++ = (GU08)((var)>>0);}while(0)
#define GPWB4(p, var) do{*(p)++ = (GU08)((var)>>24);*(p)++ = (GU08)((var)>>16); \
*(p)++ = (GU08)((var) >> 8); *(p)++ = (GU08)((var) >> 0);}while (0)
//write n bytes data to a ptr
#define GPWN(p, buf, n) do{memcpy((p), (buf), (n)); ((GU08 *)(p)) += (n);}while(0)
/***************************************************************************
*array operation macro define
***************************************************************************/
//get array element counts
#define GALEN(a) (sizeof(a) / sizeof((a)[0]))
/***************************************************************************
* for normal variable value
***************************************************************************/
//set value to variable
#define GVSET(var, value) ((var) = (value))
//judagement var1 and var2 is equal
#define GVEQ(var1, var2) ((var1) == (var2))
//judagement var1 and var2 is not equal
#define GVNE(var1, var2) ((var1) != (var2))
//judagement var1 is less than(or equal) var2
#define GVLE(var1, var2) ((var1) <= (var2))
//judagement var1 is less than var2
#define GVLT(var1, var2) ((var1) < (var2))
//judagement var1 is greater than(or equal) var2
#define GVGE(var1, var2) ((var1) >= (var2))
//judagement var1 is greater than var2
#define GVGT(var1, var2) ((var1) > (var2))
/***************************************************************************
* structure operation macro
***************************************************************************/
//initialize structure
#define GSTRUCT_INIT(a) memset(&(a), 0, sizeof(a))
//initialize structure with ptr
#define GSTRUCT_PTR_INIT(p) memset(p, 0, sizeof(*(p)))
/***************************************************************************
* assert operation macro
***************************************************************************/
//if not equal then do assert break;
#define GCEQ(val1, val2) assert(GVEQ(val1, val2))
#define GCLT(val1, val2) assert(GVLT(val1, val2))
#define GCHECK(val) assert(val)
/***************************************************************************
* Branch prediction macro
***************************************************************************/
#ifdef __GNUC__
#define GLIKELY(p) __builtin_expect(!!(p), 1)
#define GUNLIKELY(p) __builtin_expect(!!(p), 0)
#else
#define GLIKELY(p) (!!(p))
#define GUNLIKELY(p) (!!(p))
#endif
#endif //end of __GENERAL_MACRO_H__
这个头文件是仿照openMax IL层接口定义中的错误类型定义方式实现的,主要是定义了一些常用的通用错误类型,并留有余地,可自定义一些扩展错误类型。
/*****************************************************************************
* Name:general_error.h
*
* Purpose: standard header,and unified error type define
*
* Note: 'G' in macro and data type indicate 'general'
*
* Version: 0.1
*
* Developer:
wen.gu, 2016-06-23
* Modified by:
*
*
*****************************************************************************/
#ifndef __GENERAL_ERROR_H__
#define __GENERAL_ERROR_H__
#include "general_type.h"
/***************************************************************************
*
* macro declaration
*
***************************************************************************/
/***************************************************************************
*
* data structure declaration
*
***************************************************************************/
/**
* The general_error_t enumeration defines the standard Errors.
* These errors should cover most of the common failure cases. However,
* vendors are free to add additional error messages of their own as
* long as they follow these rules:
*
* 1. Vendor error messages shall be in the range of 0x90000000 to 0x9000FFFF.
*
* 2. Vendor error messages shall be defined in a header file provided
* with the plugin/component/module/library. No error messages are allowed
* that are not defined.
*/
typedef enum general_error_e
{
G_OK = 0,
G_FAIL = -1,
G_ErrorNone = G_OK,
/** There were insufficient resources to perform the requested operation */
G_ErrorInsufficientResources = (GS32) 0x80001000,
/** There was an error, but the cause of the error could not be determined */
G_ErrorUndefined = (GS32) 0x80001001,
/** The name string was invalid */
G_ErrorInvalidName = (GS32)0x80001002,
/** No target with the specified name string was found */
G_ErrorNotFound = (GS32)0x80001003,
/** One or more parameters were not valid */
G_ErrorBadParameter = (GS32)0x80001004,
/** The requested function is not implemented */
G_ErrorNotImplemented = (GS32)0x80001005,
/** The buffer was emptied before the next buffer was ready */
G_ErrorUnderflow = (GS32)0x80001006,
/** The buffer was not available when it was needed */
G_ErrorOverflow = (GS32)0x80001007,
/** The hardware failed to respond as expected */
G_ErrorHardware = (GS32)0x80001008,
/** havn't enough free memory in buffer */
G_ErrorNoMemory = (GS32)0x80001009,
/** some excecption about out of range */
G_ErrorOutOfRange = (GS32)0x8000100A,
/** No more indicies can be enumerated */
G_ErrorNoMore = (GS32)0x8000100E,
/** The target detected a version mismatch */
G_ErrorVersionMismatch = (GS32)0x8000100F,
/** The component is not ready to return data at this time */
G_ErrorNotReady = (GS32)0x80001010,
/** There was a timeout that occurred */
G_ErrorTimeout = (GS32)0x80001011,
/** this operation would block */
G_ErrorWouldBlock = (GS32)0x80001012,
/** need more data */
G_ErrorNeedMoreData = (GS32)0x80001016,
/** doesn't initialized */
G_ErrorNoInit = (GS32)0x80001017,
/** The values encapsulated in the parameter or config structure are not supported. */
G_ErrorUnsupportedCommand = (GS32)0x80001019,
/** The parameter or config indicated by the given index is not supported. */
G_ErrorUnsupportedInvokeId = (GS32)0x8000101A,
/** EOF error */
G_ErrorEOF = (GS32)0x8000101B,
G_ErrorInvalidOperation = (GS32)0x8000101C, /** invalid operation */
/** Reserved region for introducing general Standard Extensions */
G_ErrorExtensions = (GS32)0x8F000000,
/** Reserved region for introducing Vendor Extensions */
G_ErrorStartUnused = (GS32)0x90000000,
G_ErrorMax = 0x7fffffff
}general_error_t;
/***************************************************************************
*
* API declaration
*
***************************************************************************/
#endif //end of __GENERAL_ERROR_H__
以上三个文件,都是笔者自己平常使用的基本头文件,当然其中也并非十全十美,不过有此三个基本文件,在编写代码时可以省却不少功夫,尤其是编写一些跨平台的middleware层的代码更为方便。
在以后的工作中或者自己写些代码的时候,会不断的积累完善此三个头文件。除了头文件之外,还会尝试将一些基础的,通用的接口或容器等等归纳起来,实现一个小型的框架性质的library。