Wayland Misc
Expat
Expat 是一个用 C 编写的流式 XML 解析库。它在处理文件大小超出内存限制且性能和灵活性至关重要的情况下表现出色。许多应用程序、库和硬件都使用了 Expat,并且还有一些绑定和第三方封装。
以下是关于 Expat 的一些重要信息:
- 什么是 Expat? Expat 是一个流式解析器,应用程序在开始解析之前向解析器注册处理程序,以处理 XML 文档中发现的相关结构(例如开始标签等)。
- 主要特点:
- 流式解析:Expat 是流式解析器,它在解析之前注册处理程序,然后在文档中发现相关结构时调用这些处理程序。
- 适用于大文件:Expat 适用于那些文件太大而无法放入内存的情况。
- 性能优越:Expat 在解析速度和灵活性方面表现出色。
- 广泛使用:许多应用程序、库和硬件都使用了 Expat。
- 绑定和封装:Expat 还有一些绑定和第三方封装,使其更易于在不同环境中使用。
请查看 这篇介绍性文章
-
示例
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <expat.h> // 回调函数:处理开始标签 void startElement(void *userData, const char *name, const char **atts) { printf("Start element: %s\n", name); } // 回调函数:处理结束标签 void endElement(void *userData, const char *name) { printf("End element: %s\n", name); } int main() { // 创建解析器 XML_Parser parser = XML_ParserCreate(NULL); if (!parser) { fprintf(stderr, "Error creating XML parser.\n"); return 1; } // 设置回调函数 XML_SetElementHandler(parser, startElement, endElement); // XML 数据(示例) const char *xmlData = "<root><item>Apple</item><item>Banana</item></root>"; // 解析 XML 数据 if (XML_Parse(parser, xmlData, strlen(xmlData), 1) == XML_STATUS_ERROR) { fprintf(stderr, "Error parsing XML data.\n"); XML_ParserFree(parser); return 1; } // 释放解析器 XML_ParserFree(parser); return 0; }
libffi
libffi 是一个用 C 编写的可移植的外部函数接口库。它为不同的调用约定提供了一个高级别的编程接口,允许程序员在运行时调用任何由调用接口描述指定的函数。FFI 代表外部函数接口,是允许在一种语言中编写的代码调用另一种语言中编写的代码的接口。libffi 实际上只提供了完整特性的外部函数接口的最底层、与机器相关的部分。在libffi之上必须存在一个处理两种语言之间传递的值的类型转换层。
以下是关于 libffi 的一些重要信息:
-
什么是 libffi? 编译器为高级语言生成遵循某些约定的代码。其中之一是“调用约定”。“调用约定”实际上是编译器对函数参数在进入函数时的位置的一组假设。“调用约定”还指定了函数的返回值在哪里找到。有些程序在编译时可能不知道要传递给函数的参数。例如,解释器可能在运行时告知调用给定函数所使用的参数的数量和类型。libffi 可以在这些程序中使用,以提供从解释器程序到编译代码的桥梁。libffi 库为各种调用约定提供了一个可移植的高级别编程接口,允许程序员在运行时调用任何由调用接口描述指定的函数。FFI 代表外部函数接口。外部函数接口是允许在一种语言中编写的代码调用另一种语言中编写的代码的接口。libffi 实际上只提供了完整特性的外部函数接口的最底层、与机器相关的部分。在libffi之上必须存在一个处理两种语言之间传递的值的类型转换层。
-
支持的平台:libffi 已经移植到许多不同的平台。发布时,已经测试了以下基本配置:
- 架构:AArch64(ARM64)、Alpha、ARC、ARM、AVR32、Blackfin 等。
- 操作系统:Linux、iOS、Windows 等。
- 编译器:Clang、GCC、MSVC 等。
如想了解更多关于 libffi 的细节,可以查看 libffi 官方网页。
-
示例 : 在这个示例中,我们使用了 libffi 来调用标准库函数 puts,并传递了不同的字符串作为参数。这个示例展示了如何使用 libffi 动态地调用外部函数。
#include <stdio.h> #include <ffi.h> int main() { ffi_cif cif; ffi_type *args[1]; void *values[1]; char *s; ffi_arg rc; // 初始化参数信息向量 args[0] = &ffi_type_pointer; values[0] = &s; // 初始化 cif if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_sint, args) == FFI_OK) { s = "Hello World!"; ffi_call(&cif, (void (*)(void))puts, &rc, values); // rc 现在保存了对 puts 的调用结果 // 更改 s 的值后,可以再次调用 puts() s = "This is cool!"; ffi_call(&cif, (void (*)(void))puts, &rc, values); } return 0; }