阅读Sofia-SIP源码 - su模块 - su_configure.h/su_config.h/su_types.h

时间:2022-06-02 05:41:05

从Visual Studio 2010中打开SofiaSIP解决方案。在libsofia_sip_ua工程下的Header Files/win32 headers子目录下可以看到su_configure.h文件。我本来想选取su_types.h头文件来先分析。但我在su_types.h头文件的开始处看到了su_configure.h头文件。这让我想到任何一个工程,照理说都应该有一个初始确定环境信息的头文件。同理,对一个模块来说也应该有一个初始确定环境信息的头文件。因此,我就又将目标转向了su_configure.h文件。

在看过SofiaSIP的辅助文档之一 - 源码文件结构后,再来看SofiaSIP里的源码就稍微有一些经验了。现在知道在头文件的开始处可以看到如下所示注释信息的作用了:

/**@file su_configure_win32.h
*
* @b su library configuration for WIN32 (VC6/VC98)
*
* The file <su_configure_win32.h> contains configuration information needed
* by WIN32 programs using @b su library.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*
* @date Created: Thu Jan 18 15:30:55 2001 ppessi
*/
紧跟@b之后的内容是描述此文件的概述信息:su库的针对WIN32平台的配置。接下来的一段是详细描述:此头文件包含的是使用su库的WIN32程序所需的配置信息。


下面这句的作用相信应该都清楚:包括它后可以加快编译速度。

#define WIN32_LEAN_AND_MEAN

然后是下面这两句注释。这里的注释信息是说:如果需要将整个工程编译成DLL那么得移出这句(注释掉等同于移出)。现在的工程是libsofia_sip_ua,查看其属性里的配置类型,确实是”动态库(.dll)“。

/* Remove this when building DLL */
/* #define LIBSOFIA_SIP_UA_STATIC */


接着是七个#define。前面三个的用意应该很明显,是否是在WIN32平台(是)、是否有WINSOCK(是)和是否有WINSOCK2(是)。后面四个都是否:有POLL(否,因为是在WINDOWS平台)、有BSDSOCK(否),有STDINT(否,WIN32平台下没有标准的整型数据定义头文件。C99标准定义了stdint.h、inttypes.h,用于统一的跨平台数据定义。可惜VC、BCB等编译器对C99的兼容性较差,有些版本没有该头文件。)和有NT(否,具体含义不详,NT是指操作系统吗?)。

#define SU_HAVE_WIN321
#define SU_HAVE_WINSOCK 1
#define SU_HAVE_WINSOCK2 1
#define SU_HAVE_POLL 0
#define SU_HAVE_BSDSOCK 0
#define SU_HAVE_STDINT (0)
#define SU_HAVE_NT 0
前六个宏定义都是平台以及平台特性相关的。


接下来的定义都与网络有关。否符合windows平台的特性。

/* note: on Windows 2000 and older (WINVER<=500), IPv6-tech-preview
* is needed for IPv4 support as well, so SU_HAVE_IN6 must be set */
#define SU_HAVE_IN6 1 因为Windows2000也可以支持IPv6,所以设置成1。

#define SU_HAVE_PTHREADS (1) 支持PTHREADS<span style="font-family: Arial, Helvetica, sans-serif;">,因此为1</span><span style="font-family: Arial, Helvetica, sans-serif;">。</span>

/** Define as 1 if you have sa_len field in struct sockaddr */
#undef SU_HAVE_SOCKADDR_SA_LEN 没在sockaddr结构体内看到sa_len域,所以这里取消这个宏。

/** Define as 1 if you have struct sockaddr_storage */
#define SU_HAVE_SOCKADDR_STORAGE 1 widnows平台下看到有这个结构体,因此为1。

/* Define this as 1 if you have if_nameindex() */
#undef SU_HAVE_IF_NAMEINDEX 没看到有这个函数或结构体,所以这里取消这个宏。

/* Define as 1 if you have struct getaddrinfo. */
#define SU_HAVE_ADDRINFO 1 有这个函数所以为1。

这个确实和编译器有关。因为VC只支持C89,不支持C99。而C99的标准里是inline,不是__inline。SofiaSIP为了支持跨平台,不得已自己重新再定义一个宏:SU_INLINE。
#define SU_INLINE                  __inline
#define su_inline static __inline
#define SU_HAVE_INLINE (1)

下面这个,上网查了点资料没看到任何相关的信息。
/** Define this as 1 if we can use tags directly from stack. */
#define SU_HAVE_TAGSTACK (1)

下面这些与SU_INLINE相似,windows平台下的相同字节数的整型类型与linux平台下的整型类型表示不一致。SofiaSIP为了支持跨平台,不得已自己重新再定义一些宏。
#define SU_S64_T __int64
#define SU_U64_T unsigned __int64
#define SU_S32_T __int32
#define SU_U32_T unsigned __int32
#define SU_S16_T __int16
#define SU_U16_T unsigned __int16
#define SU_S8_T __int8
#define SU_U8_T unsigned __int8

#define SU_LEAST64_T __int64
#define SU_LEAST32_T __int32
#define SU_LEAST16_T __int16
#define SU_LEAST8_T __int8

数值常量的表示方法。估计又是因为平台的差异造成必须重新再定义一套。
#define SU_S64_C(i) (SU_S64_T)(i ## L)
#define SU_U64_C(i) (SU_U64_T)(i ## UL)
#define SU_S32_C(i) (SU_S32_T)(i ## L)
#define SU_U32_C(i) (SU_U32_T)(i ## UL)
#define SU_S16_C(i) (SU_S16_T)(i)
#define SU_U16_C(i) (SU_U16_T)(i ## U)
#define SU_S8_C(i) (SU_S8_T)(i)
#define SU_U8_C(i) (SU_U8_T)(i ## U)

windows平台下只有_stricmp这个函数,没有strcasecmp函数。但_stricmp函数的接口和功能与strcasecmp函数一致。因此,必须在windows平台下定义strcasecmp。其他类似。
#ifndef strcasecmp
#define strcasecmp _stricmp
#endif
#ifndef strncasecmp
#define strncasecmp _strnicmp
#endif
#ifndef snprintf
#define snprintf _snprintf
#endif
#ifndef vsnprintf
#ifndef _MSC_VER
#define vsnprintf _vsnprintf
#endif
#if _MSC_VER < 1500
#define vsnprintf _vsnprintf
#endif
#endif

#define srandom(x) srand((x))
#define random() rand()

最后一部分是有关size_t的。标准中size_t并不是一个类型,也是一个typedef。 /Wp64编译器选项和关键字 __w64已弃用,并将在编译器的未来版本中取消。

#define SOFIA_ISIZE_T size_t
#define SOFIA_USIZE_T size_t

#ifdef _WIN64
#define SOFIA_SSIZE_T __int64
#define SOFIA_ISSIZE_T __int64
#define SU_INTPTR_T __int64
#elif _MSC_VER >= 1400
#define SOFIA_SSIZE_T __int32 __w64
#define SOFIA_ISSIZE_T __int32 __w64
#define SU_INTPTR_T __int32 __w64
#else
#define SOFIA_SSIZE_T __int32
#define SOFIA_ISSIZE_T __int32
#define SU_INTPTR_T __int32
#endif

#ifndef SIZE_MAX
#define SIZE_MAX MAXINT_PTR
#endif
#ifndef SSIZE_MAX
#define SSIZE_MAX MAXUINT_PTR
#endif

#define ISIZE_MAX SIZE_MAX
#define ISSIZE_MAX SSIZE_MAX
#define USIZE_MAX SIZE_MAX

su_config.h

此头文件的大部分内容均已在这篇博文中分析过:http://blog.csdn.net/neohan/article/details/38759027。这里只列举还未触及的内容。

#ifndef SU_CONFIG_H
/** Defined when <sofia-sip/su_config.h> has been included. */
#define SU_CONFIG_H
/**@file sofia-sip/su_config.h
*
* @b su library configuration
*
* This file includes an appropriate <sofia-sip/su_configure*.h> include file.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*
* @date Created: Thu Mar 18 19:40:51 1999 pessi
*/

#ifndef SU_CONFIGURE_H
#include <sofia-sip/su_configure.h>
#endif
这里第一部分是本头文件的哨卫宏。第二部分又可以看到每个头文件都必须具备的注释信息。第三部分用Sofia软件包内包含自身库内头文件的标准方式包含sofia-sip/su_configure.h头文件。

su_types.h

此头文件的内容很见,正如其注释所表述的那样:

/**@file sofia-sip/su_types.h Basic integer types for @b su library.
*
* This include file provides <stdint.h> or <inttypes.h> types.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
* @date Created: Thu Mar 18 19:40:51 1999 pessi
*/
这个头文件提供C99标准<stdint.h>和<inttypes.h>头文件中提供的整型类型,并且给它们起了其他的名称,这样方便在库内统一使用,并且提供了跨平台特性。