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

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

 

su_config.h

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

SOFIA_BEGIN_DECLS
SOFIA_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_DECLS	extern "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__的处理没看,暂放一旁。

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值