讲师中心 微信公众号
AI工具推荐 视频效率加速

跨平台代码的3种组织方式

酷雪君_7586

酷雪君_7586

发布时间:2025-09-07 08:08:01

|

339人浏览过

|

来源于php中文网

原创

一、起源

在前一篇文章中,我分享了一个跨平台头文件的示例,该示例在 Windows 平台上更为重要,因为它需要处理库函数的导入和导出声明(dllexport、dllimport)。基于这个头文件,我们可以进一步扩展,以实现更细粒度的控制,比如对编译器和其版本的判断。

在源代码中,我们同样会遇到一些跨平台的问题。不同平台上的相同功能,实现方式可能有所不同。那么,如何有效地组织这些平台相关的代码呢?本文将探讨这个问题。

PS:文末将提供一个简单的跨平台构建代码示例。

二、问题引入

假设我们要编写一个库,需要实现一个获取系统时间戳的函数。作为库的作者,你决定提供以下API函数:

我们的任务是在函数实现中,通过不同平台下的C库或系统调用来计算系统当前的时间戳。

在Linux平台下,可以通过以下代码实现:

struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec * 1000 + tv.tv_usec / 1000;

在Windows平台下,可以通过以下代码实现:

struct timeb tp;
ftime(&tp);
return tp.time * 1000 + tp.millitm;

那么问题来了:如何将这两段平台相关的代码组织在一起?下面将介绍三种不同的组织方式,这些方式没有优劣之分,适合每个人和团队的不同习惯。

此外,这个示例中只有一个函数,而且较短。如果有许多跨平台的函数,且都很长,你的选择可能会有所不同。

三、三个解决方案

方案1

直接在接口函数中,通过平台宏定义来区分不同平台。

平台宏定义(T_LINUX, T_WINDOWS)是在前一篇文章中介绍的,通过操作系统和编译器来判断当前平台,并定义统一的平台宏供我们使用:

代码组织方式如下:

int64 t_get_timestamp() {
    int64 ts = -1;
    #if defined(T_LINUX)
        struct timeval tv;
        gettimeofday(&tv, NULL);
        ts = tv.tv_sec * 1000 + tv.tv_usec / 1000;
    #elif defined(T_WINDOWS)
        struct timeb tp;
        ftime(&tp);
        ts = tp.time;
        ts = ts * 1000 + tp.millitm;
    #endif
    return ts;
}

这种方式将所有平台代码放在API函数中,通过平台宏定义进行条件编译。由于代码较短,看起来还不错。

方案2

将不同平台的实现代码放在独立的文件中,然后通过#include预处理符号,在API函数中引入平台相关的代码。

增加两个文件:

git摸鱼周报自动化
git摸鱼周报自动化

生成周报:读取本机 Git 仓库最近一周的提交记录,按项目分类提炼总结,生成标准周报格式,通过微信推送并返回给用户。触发词:周报、weekly report、git总结、提交记录总结、工作周报。

下载

(1) t_time_linux.c

#include "t_time.h"
#include <sys/time.h>
<p>int64 t_get_timestamp() {
int64 ts = -1;
struct timeval tv;
gettimeofday(&tv, NULL);
ts = tv.tv_sec * 1000 + tv.tv_usec / 1000;
return ts;
}

(2) t_time_windows.c

#include "t_time.h"</p><h1>include <windows.h></h1><h1>include <sys/timeb.h></h1><p>int64 t_get_timestamp() {
int64 ts = -1;
struct timeb tp;
ftime(&tp);
ts = tp.time;
ts = ts * 1000 + tp.millitm;
return ts;
}

(3) t_time.c

这个文件不做任何事情,仅用于include其他代码。

#include "t_time.h"</p><h1>if defined(T_LINUX)</h1><pre class="brush:php;toolbar:false;">#include "t_time_linux.c"

elif defined(T_WINDOWS)

#include "t_time_windows.c"

else

int64 t_get_timestamp() {
    return -1;
}

endif

有些人可能不喜欢这种组织方式,因为通常我们会include头文件(.h),而这里通过平台宏定义include不同的源文件(.c),感觉有些怪异。

实际上,一些开源库也是这样做的,例如:

跨平台代码的3种组织方式

方案3

在方案2中,我们是在源代码中填入不同平台的实现代码。

实际上,我们可以换一种思路,既然已经根据平台的不同放在了不同的文件中,那么可以通过让不同的源文件加入到编译过程中来实现。

我们使用cmake工具来构建测试代码,因此可以编辑CMakelists.txt文件,来控制参与编译的源文件。

CMakelists.txt文件部分内容:

# 设置平台变量</h1><p>if (CMAKE_SYSTEM_NAME MATCHES "Linux")
set(PLATFORM linux)
elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
set(PLATFORM windows)
endif()</p><h1>根据平台变量,来编译不同的源文件</h1><p>set(LIBSRC  t<em>time</em>${PLATFORM}.c)

这种组织方式让代码看起来更“干净”。同样,我们也可以看到一些开源库也是这样做的:

跨平台代码的3种组织方式跨平台代码的3种组织方式

四、One More Thing

由于文章篇幅原因,上述仅展示了代码片段。

我编写了一个最简单的demo,使用cmake来构建跨平台的动态库、静态库和可执行程序。这个demo的主要目的是作为一个外壳,用于测试文章中的代码。

在Linux平台下,可以通过cmake指令手动编译;在Windows平台下,可以通过CLion集成开发环境直接编译和执行,也可以通过cmake工具直接生成VS2017/2019解决方案。

这个demo已上传至gitee仓库,有兴趣的小伙伴可以通过公众号dg36获取克隆地址。


热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

相关专题

更多
硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

3188

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

5149

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3849

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

486

2026.01.19

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

3339

2023.07.26

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2898

2023.07.27

windows照片无法显示
windows照片无法显示

当我们尝试打开一张图片时,可能会出现一个错误提示,提示说"Windows照片查看器无法显示此图片,因为计算机上的可用内存不足",本专题为大家提供windows照片无法显示相关的文章,帮助大家解决该问题。

1528

2023.08.01

windows查看端口被占用的情况
windows查看端口被占用的情况

windows查看端口被占用的情况的方法:1、使用Windows自带的资源监视器;2、使用命令提示符查看端口信息;3、使用任务管理器查看占用端口的进程。本专题为大家提供windows查看端口被占用的情况的相关的文章、下载、课程内容,供大家免费下载体验。

2639

2023.08.02

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

60

2026.10.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++教程
C++教程

共115课时 | 43.6万人学习

手把手实现数据传输编码
手把手实现数据传输编码

共1课时 | 940人学习

PHP面向对象基础课程(更新中)
PHP面向对象基础课程(更新中)

共12课时 | 1.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn