阅读Sofia-SIP源码一 全局宏定义

来源:互联网 发布:c语言简单的图形编程 编辑:程序博客网 时间:2024/05/18 20:46

阅读任何一个开源代码项目,最好阅读前了解作者开发这个软件前制定的一些约定。例如,命名规范,代码排版风格等。Sofia-SIP也有类似的文档,可以访问这个网页了解详情:http://sofia-sip.sourceforge.net/refdocs/styleguide.html。这些是一些通用规范,但代码中还会有一些反复出现的宏或者其他有规律性的使用方式。如果阅读前也能熟悉它们,可以加快阅读代码的速度。

 

su_config.h

打开Sofia-SIP工程中任何一个头文件,几乎总能看到这样两条语句:

SOFIA_BEGIN_DECLSSOFIA_END_DECLS

这两句分别处于头文件的开始处和结尾处。它们在sofia-sip/su_config.h头文件中定义。

/* C++ linkage needs to know that types and declarations are C, not C++.  */#if defined(__cplusplus)/** Begin declarations in Sofia header files */# define SOFIA_BEGIN_DECLSextern "C" {/** End declarations in Sofia header files */# define SOFIA_END_DECLS}#else# define SOFIA_BEGIN_DECLS# define SOFIA_END_DECLS#endif

在C++编译器下,SOFIA_BEGIN_DECLS被扩展成“extern "C" {”,“SOFIA_END_DECLS”被扩展成“}”。合并在一块就是:

extern "C" {}

这就是我们通常在写C++的Dll时经常用到的方法,防止C++变更函数名称。如果在C编译器下,两个宏被替换成空什么都没有。因为Sofia-SIP库也会在C++编译器下编译,提供给C++代码调用,所以必须加上extern这句。但如果每个头文件都写下面的语句又显得太罗嗦和繁琐:

#if defined(__cplusplus)extern "C" {#endif...#if defined(__cplusplus)}#endif

因此,Sofia-SIP的作者采用定义宏的方式。这样,每个头文件只需写两条这样的语句即可,减少了工作量,代码整体排版也显得更清洁。

既然打开了su_confg.h头文件,那就看看它里面还有什么。里面几乎都是整个项目范围内都会用到的宏定义。接着来了解SOFIAPUBFUN、SOFIAPUBVAR和SOFIACALL这三个宏。注释部分说明这些宏是为Win32平台编译链接而准备。因此,在开始处三个宏定义是为非Win32平台准备的,所以SOFIAPUBFUN和SOFIACALL的定义都是空,只有SOFIAPUBVAR可以扩展成extern。

/* ---------------------------------------------------------------------- *//* Macros required by Win32 linkage *//** SOFIAPUBFUN declares an exported function */#define SOFIAPUBFUN/** SOFIAPUBVAR declares an exported variable */#define SOFIAPUBVAR extern/** SOFIACALL declares the calling convention for exported functions */#define SOFIACALL/* Win32 linkage *//* Windows platform with MS/Borland/Cygwin/MinGW32 compiler */#if defined(_WIN32) && \  (defined(_MSC_VER) || defined(__BORLANDC__) ||  \   defined(__CYGWIN__) || defined(__MINGW32__))  #undef SOFIACALL  #define SOFIACALL __cdecl  #if defined(LIBSOFIA_SIP_UA_STATIC)  #else    #undef SOFIAPUBFUN    #undef SOFIAPUBVAR    #if defined(IN_LIBSOFIA_SIP_UA)//在LIBSOFIA_SIP_UA工程内会事先定义这个宏      #define SOFIAPUBFUN __declspec(dllexport)//因为在LIBSOFIA_SIP_UA工程内所以是输出函数      #define SOFIAPUBVAR __declspec(dllexport) extern//因为在LIBSOFIA_SIP_UA工程内所以是输出函数    #else      #define SOFIAPUBFUN __declspec(dllimport)//引入函数用      #define SOFIAPUBVAR __declspec(dllimport) extern//引入函数用    #endif  #endif  #if !defined _REENTRANT    #define _REENTRANT  #endif#elif defined (SYMBIAN)  #undef SOFIACALL  #define SOFIACALL __cdecl  #if defined(LIBSOFIA_SIP_UA_STATIC)  #else    #undef SOFIAPUBFUN    #undef SOFIAPUBVAR    #if defined(IN_LIBSOFIA_SIP_UA)      #define SOFIAPUBFUN __declspec(dllexport)      #define SOFIAPUBVAR __declspec(dllexport) extern    #else      #define SOFIAPUBFUN __declspec(dllimport)      #define SOFIAPUBVAR __declspec(dllimport)    #endif  #endif  #if !defined _REENTRANT    #define _REENTRANT  #endif#endif

这里还考虑了SYMBIAN平台,因为不熟所以不考虑了解它们,只看Win32部分。因为这三个宏都必须重定义,所以在重定义前都先解除之前的宏定义。如果未定义宏_REENTRANT(可重入的意思),则errno当作一个全局变量处理。假如你的程序是多线程的,则应当定义_REENTRANT宏,那么errno将被扩展为一个函数,该函数将访问线程局部存储的错误码。

su_config.h头文件最后部分内容如下。目的就是再为SOFIAPUBFUN生成一些别名。这些别名将在各个子模块内被使用。在子模块内这些使用,代码既显得一致规范又能少敲一些键盘。

#define BNF_DLL   SOFIAPUBFUN#define HTTP_DLL  SOFIAPUBFUN#define IPT_DLL   SOFIAPUBFUN#define AUTH_DLL  SOFIAPUBFUN#define MSG_DLL   SOFIAPUBFUN#define NEA_DLL   SOFIAPUBFUN#define NTA_DLL   SOFIAPUBFUN#define NTH_DLL   SOFIAPUBFUN#define SDP_DLL   SOFIAPUBFUN#define SIP_DLL   SOFIAPUBFUN#define SU_DLL    SOFIAPUBFUN#define TPORT_DLL SOFIAPUBFUN#define URL_DLL   SOFIAPUBFUN#define MSG_TEST_DLL SOFIAPUBFUN

 

此头文件中还剩GNUC编译器下__attrbute__的处理没看,暂放一旁。

 


0 0
原创粉丝点击