【资源】几个很受欢迎的 C 语言项目


zlog

zlog是一个高可靠性、高性能、线程安全、灵活、概念清晰的纯C日志函数库。

zlog在效率、功能、安全性上大大超过了log4c,并且是用c写成的,具有比较好的通用性。

zlog有这些特性:

  • syslog分类模型,比log4j模型更加直接了当
  • 日志格式定制,类似于log4j的pattern layout
  • 多种输出,包括动态文件、静态文件、stdout、stderr、syslog、用户自定义输出函数
  • 运行时手动、自动刷新配置文件(同时保证安全)
  • 高性能,在作者的笔记本上达到25万条日志每秒, 大概是syslog(3)配合rsyslogd的1000倍速度
  • 用户自定义等级
  • 多线程和多进程环境下保证安全转档
  • 精确到微秒
  • 简单调用包装dzlog(一个程序默认只用一个分类)
  • MDC,线程键-值对的表,可以扩展用户自定义的字段
  • 自诊断,可以在运行时输出zlog自己的日志和配置状态
  • 不依赖其他库,只要是个POSIX系统就成(当然还要一个C99兼容的vsnprintf)

zlog仓库链接:

https://github.com/HardySimpson/zlog

zlog使用手册:

http://hardysimpson.github.io/zlog/UsersGuide-CN.html

xmake

xmake是一个跨平台的安装(编译)工具。

xmake 是一个基于 Lua 的轻量级跨平台构建工具,使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能快速入门,能够让用户把更多的精力集中在实际的项目开发上。

xmake官网:

https://xmake.io/

1、支持的平台

  • Windows (x86, x64)
  • macOS (i386, x86_64, arm64)
  • Linux (i386, x86_64, cross-toolchains ..)
  • *BSD (i386, x86_64)
  • Android (x86, x86_64, armeabi, armeabi-v7a, arm64-v8a)
  • iOS (armv7, armv7s, arm64, i386, x86_64)
  • WatchOS (armv7k, i386)
  • MSYS (i386, x86_64)
  • MinGW (i386, x86_64, arm, arm64)
  • Cygwin (i386, x86_64)
  • Wasm (wasm32)
  • Cross (cross-toolchains ..)

2、支持的工具链

3、支持的语言

  • C/C++
  • Objc/Objc++
  • Swift
  • Assembly
  • Golang
  • Rust
  • Dlang
  • Fortran
  • Cuda
  • Zig (Experimental)

4、编译测试

多任务并行编译测试:

单任务编译测试:

官网上的内容很丰富,对xmake做了很详细的介绍,感兴趣的小伙伴可以自己去了解学习。

gear-lib

gear-lib是一组通用的C基础库。

  • 全部用POSIX C实现,目标是为了跨平台兼容linux, windows, android, ios。
  • 适用于物联网,嵌入式,以及网络服务开发等场景。

包含如下内容:

gear-lib使用起来很方便,可以作为我们日常开发中的工具库。

gear-lib地址:

https://github.com/gozfree/gear-lib

inih

inih是一个C 语言编写的 INI 文件解析器。

ini 文件是 Initialization File 的缩写,即初始化文件。INI文件由节、键、值组成,注解使用分号表示(;)

例子:

[ip]                ;Section1
ip_addr = 192.168.1.103

[test]              ;Section2
name = ZhengN       
num  = 66  
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ini.h"

typedef struct
{
    const char* ip_addr;
    const char* name;
    int num;
} configuration;

static int handler(void* user, const char* section, const char* name,
                   const char* value)
{
    configuration* pconfig = (configuration*)user;

    #define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0
    if (MATCH("ip", "ip_addr")) 
    {
        pconfig->ip_addr = strdup(value);
    } 
    else if (MATCH("test", "name")) 
    {
        pconfig->name = strdup(value);
    } 
    else if (MATCH("test", "num")) 
    {
        pconfig->num = atoi(value);
    } 
    else 
    {
        return 0;  /* unknown section/name, error */
    }

    return 1;
}

int main(int argc, char* argv[])
{
    configuration config;
    config.ip_addr = NULL;  /* set defaults */
    config.name = NULL;
    config.num = 0;

    if (ini_parse("ip.ini", handler, &config) < 0) 
    {
        printf("Can't load 'ip.ini'\n");
        return 1;
    }
    printf("Config loaded from 'ip.ini': ip_addr = %s, name = %s, num = %d\n",
        config.ip_addr, config.name, config.num);

    if (config.ip_addr)
        free((void*)config.ip_addr);
    if (config.name)
        free((void*)config.name);

    return 0;
}

queue

queue.h是Linux、FreeBSD中的一个很实用的头文件。这个头文件里全是宏定义操作,所以其不仅可以使用在Linux/嵌入式Linux项目中,也可以使用在单片机项目中。

它使用宏实现了如下数据结构:

  • SLIST:单向无尾链表
  • LIST:双向无尾链表
  • STAILQ:单向有尾链表(可作队列使用)
  • TAILQ:双向有尾链表(可作队列使用)

所有的数据结构都支持如下功能:

  • 在链表头插入节点
  • 在任意节点后插入节点
  • 删除节点
  • 遍历节点

我们可以在Linux系统的如下路径中找到这个头文件:

/usr/include/sys/queue.h

也可以通过如下网址查看:

https://code.woboq.org/userspace/glibc/misc/sys/queue.h.html

/*
 * Singly-linked List definitions.
 */
#define	SLIST_HEAD(name, type)									\
struct name {								       				\
	struct type *slh_first;	/* first element */	    			\
}

#define	SLIST_HEAD_INITIALIZER(head)							\
	{ NULL }

#define	SLIST_ENTRY(type)										\
struct {														\
	struct type *sle_next;	/* next element */					\
}

/*
 * Singly-linked List functions.
 */
#define	SLIST_INIT(head) do {									\
	(head)->slh_first = NULL;									\
} while (/*CONSTCOND*/0)

#define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
	(elm)->field.sle_next = (slistelm)->field.sle_next;			\
	(slistelm)->field.sle_next = (elm);							\
} while (/*CONSTCOND*/0)

#define	SLIST_INSERT_HEAD(head, elm, field) do {				\
	(elm)->field.sle_next = (head)->slh_first;					\
	(head)->slh_first = (elm);									\
} while (/*CONSTCOND*/0)

#define	SLIST_REMOVE_HEAD(head, field) do {						\
	(head)->slh_first = (head)->slh_first->field.sle_next;		\
} while (/*CONSTCOND*/0)

#define	SLIST_REMOVE(head, elm, type, field) do {				\
	if ((head)->slh_first == (elm)) {							\
		SLIST_REMOVE_HEAD((head), field);						\
	}															\
	else {														\
		struct type *curelm = (head)->slh_first;				\
		while(curelm->field.sle_next != (elm))					\
			curelm = curelm->field.sle_next;					\
		curelm->field.sle_next =								\
		    curelm->field.sle_next->field.sle_next;				\
	}															\
} while (/*CONSTCOND*/0)

#define	SLIST_FOREACH(var, head, field)							\
	for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)

/*
 * Singly-linked List access methods.
 */
#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
#define	SLIST_FIRST(head)	((head)->slh_first)
#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)

cJSON

https://github.com/DaveGamble/cJSON.git

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

cJSON是C语言编写的用于解析与组包JSON数据的一个库。

protobuf

https://github.com/protocolbuffers/protobuf

Protocol Buffers,是Google公司开发的一种数据格式,类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面。它不依赖于语言和平台并且可扩展性极强。

JSON类型数据可读性很好,但是整个数据包中会带有一些无用的数据,自然会在一定程度上带来通信负担。protobuf是一种相对JSON来说更为轻量的数据格式。

protobuf的优点:

  • 可扩展性强。
  • 消息格式升级和兼容性好
  • 支持跨平台多语言
  • 序列化反序列化速度很快
  • 序列化后体积相比Json和XML很小,适合网络传输


文章作者: 杂烩君
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 杂烩君 !
  目录