最近,我正在学习 C++ 中的网络,我发现 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span id=image>https://via.placeholder.com/150</span>
<button id="load">Load Image</button>
<img id="imageDisplay">
是一个跨平台的库,然后我想到了这个库是如何跨平台的,因为 Windows 为网络提供了不同的库,甚至麦克也,
那么它的功能如何在不同的机器上工作,跨平台库是否为此创建了自己的函数,或者它们包含不同机器逻辑的不同私有函数并提供公共函数,然后在编译时检查代码在哪台机器上编译和更改我们使用机器定义的库编写的函数。
例如
boost.asio
可能的解决方案可能是?
答案 0 :(得分:1)
这通常是使用特定于编译器的宏来完成的。例如,gcc
编译器定义了预处理器符号
__linux
在 Linux 上。所以,C 或 C++ 代码可以使用
#if __linux
编译 Linux 特定的代码。实际代码中实际上没有任何内容#define
。这是默认情况下由 gcc
的 Linux 版本定义的。 gcc
支持的其他平台上定义了类似的预处理器宏。其他编译器具有类似的预定义宏。跨平台库的源代码将它们检查的这些宏集合在一起,以便编译特定于操作系统的代码。
另一种常见的方法是将特定于库的符号明确定义为库构建指令或脚本的一部分。跨平台库附带的构建指令包括从库包中运行适当脚本的指令,该脚本运行编译器并显式设置适当的预处理器符号,然后以这种方式使用。
通常,在现代 C++ 代码中不鼓励使用预处理器,并谨慎使用。这是一种在实践中使用预处理器宏非常常见的用例。
答案 1 :(得分:1)
有几种可能的方法:
char* doFoo(void){
#ifdef _WIN32
return "win32";
#elif ...
return ...;
#endif ...
}
优点是不需要太多设置。
缺点是,如果你做得太多,它会使代码混乱。
作为文件夹结构:
root
|---->Other files
|---->windows implementation
| |->foo.c
|---->linux implementation
|->foo.c
|---->macos implementation
|->foo.c
然后你可以使用一些构建系统,或者一个自定义的 shell 脚本来选择东西。
(伪代码)
if(OS==windows)
compileDirectory(windowsImpl);
else if(OS==linux)
compileDirectory(windowsImpl);
if(OS==macos)
compileDirectory(windowsImpl);
优点是,它不会使代码混乱,允许更好地添加新功能和某种抽象。
相反的是,它的设置可能非常繁琐。
答案 2 :(得分:1)
通常跨平台库是分层实现的。
有公共接口、通用代码和一组最小化的平台相关代码。
公共接口通常使用 #if defined(symbol)
检查来确定它在哪个平台上运行。它可能包含基于此的系统标头,但更常见的是简单地转发声明它需要为特定于平台的 API(如果有)公开的任何符号。在某些情况下,只有头文件的库会比这更进一步。
通用代码中将包含最少的平台特定内容。它将尝试使用抽象处理平台特定的东西;它可能 #include
平台特定的帮助程序标头,但代码在平台之间是通用的。
比如,它可能会使用 Native::RWLock
和 Native::RWLock::lock( mutex )
函数,这些函数是针对平台特定类型的 typedef 和瘦包装器。
平台特定代码因平台而异。它可以在构建系统 NativeMutexImp_mac.cpp
中有条件地编译,或者包装在 #ifdef
块中,甚至两者都包含。
现在只有头文件的库比这更泄漏。一些组织较少的跨平台代码将混合特定平台而不是到处都是代码。最后,性能要求可能需要在公共头文件中泄漏一些特定于平台的代码。
但主要思想是隐藏操作系统 API 的使用,而这些使用又用于实现跨平台功能。
这可以使最终用户代码比使用原生 OS API 更快如果您的 API 比原生 API 更容易高效使用。优化是可替代的;更容易提高性能的代码实际上在实践中更快。