c语言边角料5:一个跨平台的头文件
时间:2021-11-05 14:09:36
手机看文章
扫描二维码
随时随地手机看文章
[导读]一、前言二、头文件三、预定义的宏四、Windows平台场景分析五、Linux平台场景分析一、前言我们平常在写代码的时候,特别是在制造轮子的时候(为别人提供库文件),会遇到各种不同的需求场景:有些人需要在Linux系统下使用,有些人需要在Windows系统下使用;有些人使用C语言开...
-
一、前言
-
二、头文件
-
三、预定义的宏
-
四、Windows 平台场景分析
-
五、Linux 平台场景分析
一、前言
我们平常在写代码的时候,特别是在制造轮子的时候(为别人提供库文件),会遇到各种不同的需求场景:
特别是在 Windows 系统中,库文件中导出的函数需要使用 _declspec(dllexport) 来声明函数,而使用者在导入的时候,需要使用 _declspec(dllimport) 来声明函数,甚是麻烦!
- 有些人需要在 Linux 系统下使用,有些人需要在 Windows 系统下使用;
- 有些人使用 C 语言开发,有些人使用 C 来开发;
- 有些人使用动态库,有些人使用静态库;
二、头文件
先直接上代码,可以先试着分析一下,后面我们再逐一分析不同的使用场景。
下面是头文件:
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
#define MY_WIN32
#elif defined(linux) || defined(__linux) || defined(__linux__)
#define MY_LINUX
#endif
#if defined(MY_WIN32)
#ifdef MY_API_STATIC
#ifdef __cplusplus
#define MY_API extern "C"
#else
#define MY_API
#endif
#else
#ifdef MY_API_EXPORTS
#ifdef __cplusplus
#define MY_API extern "C" __declspec(dllexport)
#else
#define MY_API __declspec(dllexport)
#endif
#else
#ifdef __cplusplus
#define MY_API extern "C" __declspec(dllimport)
#else
#define MY_API __declspec(dllimport)
#endif
#endif
#endif
#elif defined(MY_LINUX)
#ifdef __cplusplus
#define MY_API extern "C"
#else
#define MY_API
#endif
#endif
三、预定义的宏
假设需要写一个库文件,提供给别人使用。定义了上面这个头文件之后,其他的文件中都要 include 这个头文件。
1. 平台宏定义
不同的平台预定义了相应的宏定义,例如:
Windows 平台:WIN32, _WIN32, WIN32;在一个确定的平台上,这些宏不一定全部定义,很可能只有其中的某一个宏是被定义的。
Linux 平台:linux, __linux, linux;
2. 编译器宏定义
如果在写库代码的时候,使用的是 C ,而使用者使用的是 C 语言,那么就需要对库函数进行 extern “C” 声明,让编译器不要对函数的名称进行改写。
四、Windows 平台场景分析
1. 编译生成库文件
(1) 生成静态库
gcc 编译器:#define MY_API(2) 生成动态库
g 编译器:#define MY_API extern "C"
gcc 编译器:#define MY_API __declspec(dllexport)g 编译器:#define MY_API extern "C" __declspec(dllexport)
2. 使用库
在使用库的应用程序中,也需要在代码中 include 这个头文件,然后加上编译选项中定义的各种宏,来生成对应的MY_API宏定义。
gcc 编译器:#define MY_API(2) 使用动态库
g 编译器:#define MY_API extern "C"
gcc 编译器:#define MY_API extern "C" __declspec(dllimport)这样就相当于声明导入库函数了。g 编译器:#define MY_API __declspec(dllimport)
五、Linux 平台场景分析
Linux 平台下就简单多了,只需要注意编译器的问题,而没有导出和导入之分。