C/C++ 程序库
C/C++ 程序库
// ---------------------------------------------
来几个不常见但是很变态的库吧:
bundle: 把几乎所有常见的压缩库封装成了一个库, 接口完全统一, 想用哪个用哪个.
就一个h和一个巨TM大的cpp文件,巨好使巨方便.
Celero: 简单清晰的benchmark库, 特点就是简单易用没有废话.
getopt: 解析命令行输入参数的库, 好使! 没废话! 就俩文件.
stb_image: 常见图片格式加载库, 就一个巨大无比的头文件
stb_truetype: 常见字体加载库, 就一个巨大无比的头文件, 觉得freetype大的可以用它.
都在这: nothings/stb
better-enums: 编译期实现的enum扩展功能,包括enum和字符串互转等等. 感觉比较重量级, 我一般是不用的, 但有时候没它还真是别扭, 尤其是需要把一个enum序列化的时候.
Catch2: 著名的单元测试框架, 那么它和boost或者google的单元测试框架有什么不同呢?
就在于它首先是header only的, 其次是没有废话,直击要害! 你要测试对吧? 给你!
uchardet: 实现猜字符串编码的功能, 例如输入一个不知道编码的文本文件, 它可以帮你"猜" 这个文件的编码是什么. 和python里的uchardet功能基本一样.
win-iconv: iconv库是一个字符集编码转换的库, 在linux和mac下均是原生字符转换库. 但windows上并不是自带的. 那么就会导致在windows上编译iconv有点浪费. 因为windows显然已经自带字符集转换的功能了. 那么这个库的作用就是用windows api来实现和iconv库一模一样的接口. 这样编译出来比较小. 从此字符转换不是梦.
freetype-gl: open gl 上实现的freetype. 不过我个人没用过... 不知道好不好用. 但当你需要在opengl上下文中渲染字体的时候, 你可能用得着它.
nanovg: 基于openGL/DX/metal的2d绘图库. 绘图效率高, 接口清晰. 主版本是基于openGL的, 但有DX,metal等分支. 前端接口还有python和lua的. 个人感觉不错.
imgui: 大名鼎鼎的imgui, 你可能会问在有一堆GUI框架的情况下为什么我们需要imgui? 因为它是immediate mode的. 个人认为是几个immediate mode的GUI框架里最好的. 详细见它的页面介绍.
spdlog: logger库, 重点推荐! 为什么呢? 因为好使! 没有废话. 而且是header only的.
ffts: 很好使的FFT库, 和fftw的不同在于用着是真方便! 而且难能可贵在于速度居然真不比fftw慢.
fmt: formatting库, 又小又好使! 太好使了!
最后是恐怖的Amalgamate.
它是干嘛的呢? 它是专门用来把其他库"封装成"一个cpp和一个h文件的工具. 比如说freetype里有几十个h几十个cpp, 用起来觉得麻烦的话, 就写个配置文件然后用它跑一下, 立即就可以把freetype的这些cpp和h文件变成仅仅两个巨大无比的cpp和h文件. 再重复一遍, 巨大无比!! 这便是传说中的unity build.... 目前github上已经有很多的人开始用它来封装一些常见的库了.
这样做有什么好处呢? 比如说有个库,
那么这么做好不好呢, 我也不知道. 前文中提到的bundle库就是用它把N多库合并到一个cpp里的.
这个工具的作者vinniefalco还写了beast库, 目前已收录进了boost里.
freetypeAmalgam: 利用上面的工具把整个freetype封装成了一个h和一个cpp, 想用freetype又懒得编译和配置的人就把这两个文件往项目里一拖, 就可以用freetype了.
//--------------------------------------------------
再补充几个吧:
上面说的iconv的win32实现复杂了一点, 这个更简单:
https://github.com/win-iconv/win-iconv
PFFFT: 又一个FFT库, 那么你也许会问它和FFTW相比如何呢? 它的好处就是真的很小! 两个文件往项目里一拖就行了:
https://github.com/marton78/pffft
bgfx: 超恐怖的跨平台图形渲染库, windows mac linux ios 安卓html...跨的平台基本全了, 它的后端就更可怕了, DX, opengl, metal... 连webgl都有. 我不怎么搞这方面, 也不知道好不好使, 我只是觉得很牛就放这里了:
scriptorium: 这个就不算是库了, 是几乎所有你听说过的没听说过的常见用于游戏脚本的语言的benchmark, 可以不去研究, 但不妨看看:
tinyexpr: 我特别喜欢的数学表达式解析和计算库, 真的好用而且小, 专门用来实现在程序运行时解析用户输入的数学表达式并做计算的库, 只有两个文件, 往项目里一拖就行了:
matplotcpp: 在C++中绑定python的matplot库.
// ---------------------------------------------
A. 自己写一遍太累
B. 写得很好
C. 实用且满足我的需求
D. 好用不折腾
E. 代码有深度且可读性高,可以挖宝贝
- AC: 3D 模型解析 assimp/assimp
- ACE: 物理模拟 bulletphysics/bullet3
- AB: 渲染中间层 bkaradzic/bgfx
- CD: 3D灵感宣泄场所 cinder/Cinder // 后来发现 Houdini 更好玩
- CD: 命令行帮助既是命令行解析 https://github.com/docopt/docopt.cpp
- ACD: printf 不好用,ostream 也不好用,format 好用 fmtlib/fmt
- ABCD: 3D 数学运算 g-truc/glm
- ABCD: 拿来就能用的 UI ocornut/imgui
- D: json 结构用在 C++ 里面就像在 JS 里面一样自然 nlohmann/json
- BCD: 超高校级的 json 解析 Tencent/rapidjson
- ABCD: 用过都知道它的好的性能分析工具 jonasmr/microprofile
- CD: 又快又不折腾的 xml 解析 zeux/pugixml
- ACD: 专注寻路 recastnavigation/recastnavigation
- ACD: 什么都能放到头文件中 nothings/stb
- D: 一键生成 C/C++ 对各种其他语言的接口 swig/swig
- ACD: 最快的哈希算法 Cyan4973/xxHash
- E: 包含大量计算几何算法的 Geometric Tools
- E: 包含最经典渲染算法的 mmp/pbrt-v3
Update: 再加两个没人提的
- BCD: 又小又快又方便的单元测试库,嗯测试很重要: onqtam/doctest
- ABCDE: 高精度浮点数运算库,Fabrice Bellard 一出手总是把很复杂的东西弄得跟玩似的,境界真的高: LibBF Library
// ---------------------------------------------
做存储, 数据库系统方面的开发,主要用到
* grpc/libevent/libev/libasio 实现高性能网络服务器* protobuf 数据结构序列化/反序列化,方便数据交换
* LevelDB/RocksDB 嵌入式KV数据库
* snappy/zlib/lz4 数据压缩,解压缩
* jemalloc/tcmalloc 高效内存分配器,尤其多线程场景
* jerasure Reed Solomon编解码,给存储系统实现erasure code
* murmurhash… 实现hash摘要
* crc32 数据存储或传输时的数据校验
* cJSON 解析json格式配置文件
* libBSON JSON序列化/反序列化,MongoDB使用这种格式存储数据
* boost 功能丰富的C++基础库,轻度使用,C++11/14后基本不用了。
* libRedis redis是一个数据库服务,并不是单独的库,但其代码精简,质量非常高,里面很多代码都可以拿出来直接复用,比如网络,各种数据结构的实现。
// ---------------------------------------------
// ---------------------------------------------
stl就不说了, 目前后端开发,常用库
字符串算法库 Boost String Algorithms Library
IO框架 Boost.asio boost.fiber boost.beast 组合起来就是一个基于协程的io框架
堆栈跟踪 Boost.Stacktrace 需要配合libbacktrace库
CRC验证 Boost.CRC
日期时间库 Boost.Date_Time
uuid Boost.Uuid
类型转换 Boost.Lexical_Cast 注,这货可以转boost里的很多类型,比如 uuid ptime date等,不需要其它处理
命令行输入参数解析 Boost.Program_options
随机数 Boost.Random
各种字符集转换 Boost.Locale 这货本地化库,功能很多,我一般只用它的字符集互转
文件系统 Boost.Filesystem 一般只是用它来判断文件存不存在,拼路径,用的功能比较少
Log库 Boost.Log 很强大的日志系统,要同步有同步,要异步只需要改几行代码,支持syslog,注意不支持 syslog RFC5424规范,只支持比较老的 RFC3164规范,我参考 boost log库里的实现和RFC5424格式弄了个简单的包装。
异常库 Boost Exception 配合Boost.Stacktrace可以抛出带堆栈信息的异常类。
http/2库 nghttp2 苹果推送需要http/2
数据库方面 soci,可以拉最新master分支代码,可以hook断线重连,有了这个,配合数据库主从集群模式,在主库故障时,从库升为主库时,服务可以自动连新的主库,完全不用人工干预,是不是很省心,不过这功能只支持postgresql和oracle数据库,虽然pg-pool数据库网关也可以实现postgresql 类似的功能,但以前遇到过在主从模式无任何故障下,更新数据后马上查询,查到的数据有概率不是刚更新的,应该是被pg-pool分到了从库去查了。 另外可以容易扩展自定义类型支持,比如boost uuid ptime类型,只需写2个类型转换函数就支持了。
libssh2 这个库我一般不用它来加密,只是用它来做反向隧道和正向隧道,不了解的可以百度下。
cpp-jwt 这个库用来JSON Web Token JWT验证,苹果推送需要这玩意
json 一个只有头文件的json库,不多说很强大很现代c++
一个抛出错误码和0到8层堆栈信息的简单函数
typedef boost::error_info<struct tag_stacktrace, boost::stacktrace::stacktrace> exception_stack;
typedef boost::error_info<struct tag_global_error_code, int> exception_error_code;
template <class E>
void throw_with_trace_code(const E &e, int ecode)
{
throw boost::enable_error_info(e)
<< exception_stack(boost::stacktrace::stacktrace(0, 8)) << exception_error_code(ecode);
}
一个参考boost log库中syslog实现, 支持RFC5424规范的syslog实现
namespace boost {
BOOST_LOG_OPEN_NAMESPACE
namespace sinks {
class syslog_udp5424_backend :
public basic_formatted_sink_backend< char >
{
//! Base type
typedef basic_formatted_sink_backend< char > base_type;
typedef boost::log::aux::light_function< syslog::level (record_view const&) > severity_mapper_type;
public:
/*!
* Constructor. Creates a UDP socket-based backend with <tt>syslog::user</tt> facility code.
* IPv4 protocol will be used.
*/
BOOST_LOG_API syslog_udp5424_backend() : m_socket(m_service)
{
}
/*!
* Destructor
*/
BOOST_LOG_API ~syslog_udp5424_backend()
{
}
BOOST_LOG_API void set_severity_mapper(severity_mapper_type const& mapper)
{
m_level_mapper = mapper;
}
BOOST_LOG_API void set_target_address(std::string const& addr, unsigned short port = 514)
{
m_process_name = boost::log::aux::get_process_name();
if(m_process_name.empty())
{
m_process_name = "-";
}
m_process_id = boost::lexical_cast<string>(boost::log::aux::this_process::get_id().native_id());
boost::system::error_code ec;
m_local_hostname = asio::ip::host_name(ec);