- 数据工程
- 大数据
- 序列化
- 数据分析
【免费下载链接】arrow
Apache Arrow is a multi-language toolbox for accelerated data interchange and in-memory processing
Apache Arrow GLib 是 Apache Arrow 在 C 语言生态中的官方绑定层:它以 GLib/GObject 惯用法重新包装 Arrow C++,对外提供稳定的 C API,并借助 GObject Introspection(GI)自动生成 Ruby、Lua、Python 等语言的运行时绑定。本文以仓库中的 docs/source/c_glib/index.md 为骨架,结合 c_glib/README.md、Meson 构建配置与c_glib/下的真实源码与示例,完整讲解其架构定位、模块全景、构建安装、C 语言使用、语言绑定与单元测试,让读者既能直接上手编译运行,也能理解 GI 机制在底层如何工作。
Arrow GLib 是什么:给 C 语言一套「可自省」的 Arrow API
Apache Arrow GLib 是 Apache Arrow C++ 的包装库(wrapper library),它为 Arrow C++ 提供了完整的 C API。正如 docs/source/c_glib/index.md 所述,Arrow GLib 的核心价值有两点:
- 面向 C 的稳定接口:把 Arrow C++ 的模板化、命名空间化的 C++ 类型,映射为以
GArrow为前缀的 GLib 对象(如GArrowArray、GArrowRecordBatch、GArrowSchema),并遵守 GLib 的引用计数、GError错误传递与信号机制; - 支持 GObject Introspection:这意味着你可以在运行时或编译时自动生成语言绑定,无需为每种语言手工维护一套绑定代码。
在源码层面,这种包装关系清晰可见:c_glib/arrow-glib/arrow-glib.h 是 C 使用者的统一入口头文件,它先引入<glib-object.h>,再依次聚合数组、构建器、数据类型、计算、表达式、内存池、RecordBatch、Schema、Table、输入输出流、IPC Reader/Writer、文件系统等全部子模块头文件。所有包装类型通过 GLib 的G_DECLARE_*_TYPE宏声明(例如 c_glib/arrow-glib/reader.h 中的GArrowRecordBatchFileReader),底层则持有对应的arrow::RecordBatchReader等 C++ 对象指针,实现「C 壳 + C++ 核」的经典模式。
依托 GObject Introspection 的绑定生成机制
Arrow GLib 并不要求调用方直接面对 C 函数。GObject Introspection 会从GArrow*类型与函数导出GIR(GObject Introspection Repository)元数据,即.gir文件与编译后的.typelib,语言绑定库(如 Ruby 的gobject-introspectiongem、Lua 的 LGI、Python 的 PyGObject)读取这些元数据后即可在运行时把 C 类型映射为对应语言的对象。
c_glib/README.md给出的 Ruby 示例直观展示了「运行时生成绑定」的效果:
# Generate bindings at runtime require "gi" Arrow = GI.load("Arrow") # Now, you can access arrow::BooleanArray in Arrow C++ by # Arrow::BooleanArray p Arrow::BooleanArray也就是说,GI.load("Arrow")一行代码之后,Ruby 中就能以Arrow::BooleanArray直接操作 C++ 的arrow::BooleanArray。c_glib/README.md同时指出:在 Ruby 场景下应优先使用基于该 gem 的red-arrow,它在原生绑定之上补充了大量便捷特性。
这套元数据由构建系统自动生成:c_glib/meson.build中通过 Meson 的gnome模块以nsversion: '1.0'生成并安装 GIR/typelib(gir_dir = .../datadir/gir-1.0),而 c_glib/doc/arrow-glib.toml.in 则声明了ArrowCUDA-1.0、ArrowDataset-1.0、ArrowFlight-1.0、ArrowFlightSQL-1.0、Gandiva-1.0、Parquet-1.0等关联命名空间,构成完整的 GLib 家族元数据图谱。
GLib 家族模块全景
docs/source/c_glib/index.md的核心是一份 API 参考手册导航,它列出了 Arrow GLib 家族的全部成员。每个模块在 c_glib/ 下都有独立子目录,并与 Arrow C++ 的对应能力一一对应:
| 文档入口(docs 源) | 源码目录 | 对应 Arrow C++ 能力 |
|---|---|---|
| Apache Arrow GLib | c_glib/arrow-glib/ | 核心数据结构:Array、RecordBatch、Schema、Table、IPC、计算、文件系统等 |
| Apache Arrow CUDA GLib | c_glib/arrow-cuda-glib/ | GPU(CUDA)内存与设备间传输 |
| Apache Arrow Dataset | c_glib/arrow-dataset-glib/ | Dataset/Scanner 分区数据集读取 |
| Apache Arrow Flight GLib | c_glib/arrow-flight-glib/ | Flight RPC 客户端与服务端 |
| Apache Arrow Flight SQL GLib | c_glib/arrow-flight-sql-glib/ | Flight SQL 协议客户端与服务端 |
| Apache Parquet GLib | c_glib/parquet-glib/ | Parquet 文件读写与元数据 |
| Gandiva GLib | c_glib/gandiva-glib/ | 表达式编译与向量化求值 |
这些子模块并不是无条件编译的:从 c_glib/meson.build 可以看出,构建时通过dependency()/find_library()探测 Arrow C++ 的arrow-dataset、arrow-flight、arrow-flight-sql、gandiva、parquet、arrow-cuda等库是否可用,只有对应依赖存在时才进入相应子目录构建(如arrow_cuda.found()时才subdir('arrow-cuda-glib'))。其中arrow-acero是强制依赖,arrow-orc则通过编译探测判断。这意味着 Arrow GLib 的安装形态会根据本地 Arrow C++ 的编译选项而增减模块,与官方文档导航中的模块列表保持一致。
构建与安装 Arrow GLib
官方推荐直接使用发行版软件包(安装指引见 Apache Arrow 官方安装页),本文重点说明仓库内自带的两种构建路径:面向用户的稳定源码包构建,与面向开发者的源码树构建。两者都基于Meson + Ninja。
前置条件:先装好 Arrow C++
Arrow GLib 是对 Arrow C++ 的包装,因此第一步必须是构建并安装 Arrow C++(make install或cmake --build ... --target install)。若缺失,链接阶段会报cannot find -larrow。这是c_glib/README.md中列出的头号常见问题。
用户构建(使用发布源码包)
用户应从官方发布源码包构建(以 12.0.0 为例,替换为实际版本号):
$ wget 'https://www.apache.org/dyn/closer.lua?action=download&filename=arrow/arrow-12.0.0/apache-arrow-12.0.0.tar.gz' \ --output-document apache-arrow-12.0.0.tar.gz $ tar xf apache-arrow-12.0.0.tar.gz $ cd apache-arrow-12.0.0macOS 需先安装依赖清单,然后与其他平台一样执行:
$ brew bundle --file=c_glib/Brewfile # 仅 macOS $ meson setup c_glib.build c_glib --buildtype=release $ meson compile -C c_glib.build $ sudo meson install -C c_glib.build开发者构建(在源码树内)
开发者需要额外的GTK-Doc(用于生成 API 文档)与GObject Introspection开发包。仓库 README 按发行版给出了安装命令:
- Debian GNU/Linux / Ubuntu:
sudo apt install -y -V gtk-doc-tools libgirepository1.0-dev meson ninja-build - CentOS 7:
sudo yum install -y gtk-doc gobject-introspection-devel ninja-build,再用pip3安装 meson - CentOS 8 及以后:
sudo dnf install -y --enablerepo=powertools gtk-doc gobject-introspection-devel ninja-build,同样pip3 install meson - macOS(Homebrew):
brew bundle --file=c_glib/Brewfile
随后构建(macOS 需先设置 XML catalog 环境变量):
$ export XML_CATALOG_FILES="$(brew --prefix)/etc/xml/catalog" # 仅 macOS $ meson setup c_glib.build c_glib -Dgtk_doc=true $ meson compile -C c_glib.build $ sudo meson install -C c_glib.build注意(针对 macOS):构建 Arrow GLib 时默认链接的是 Homebrew 安装的 Arrow C++,若 GLib 层与 C++ 库之间存在版本不匹配可能导致构建失败。此时应指向本地构建的 Arrow C++,用
--cmake-prefix-path显式指定路径:$ meson setup c_glib.build c_glib --cmake-prefix-path=${arrow_cpp_install_prefix} -Dgtk_doc=true
Meson 构建选项详解
c_glib/meson_options.txt 定义了可用的构建选项,开发者可按需组合:
| 选项 | 类型/默认值 | 说明 |
|---|---|---|
arrow_cpp_build_dir | string,默认空 | 指定未安装的 Arrow C++ 构建目录,用于直接链接本地构建产物 |
arrow_cpp_build_type | string,默认release | 传给 Arrow C++ 的-DCMAKE_BUILD_TYPE值 |
doc/gtk_doc | boolean,默认false | 是否生成文档(gtk_doc为新的选项名,要求 Meson ≥ 0.63.0) |
source_reference | string,默认main | GI-DocGen 生成文档时引用的源码 URL 分支/标签 |
vapi | boolean,默认false | 是否额外生成 Vala 语言绑定(需gobject-introspection-1.0存在) |
其中arrow_cpp_build_dir对应meson.build中的逻辑:若设置该选项,Meson 会直接用find_library从{build_dir}/{build_type}目录定位libarrow、libarrow_acero等库,并从../cpp/src引入头文件,从而在不安装 Arrow C++ 的情况下完成构建。
常见构建问题排查
c_glib/README.md汇总了四类高频问题及解法:
cannot find -larrow:确认 Arrow C++ 已make install;Linux 上还需执行sudo ldconfig。unable to load .../chunk.xsl(macOS):设置export XML_CATALOG_FILES="$(brew --prefix)/etc/xml/catalog"。Symbol not found ... libsource-highlight.4.dylib(macOS):升级source-highlight(brew upgrade source-highlight)。测试时 typelib 加载失败:
dependent dylib '@rpath/...' not found(macOS):Arrow C++ 不能使用@rpath安装名,需以-DARROW_INSTALL_NAME_RPATH=OFF重新构建并安装 Arrow C++:$ cmake -S cpp -B cpp.build -DARROW_INSTALL_NAME_RPATH=OFF ... $ cmake --build cpp.build $ sudo cmake --build cpp.build --target install
使用方式一:纯 C API
C 语言使用者直接使用GArrow*系列 API。安装后,API 参考文档默认位于/usr/local/share/gtk-doc/html/arrow-glib/(若通过--prefix指定了安装前缀,路径会随之变化)。
从文件读取 RecordBatch:read-file.c 全流程解析
c_glib/example/read-file.c 是官方提供的完整可运行示例,演示了「内存映射文件 → 文件格式 Reader → 逐批读取并打印」的完整链路:
- 打开输入流:
garrow_memory_mapped_input_stream_new(input_path, &error)创建GArrowMemoryMappedInputStream,失败时打印error->message并释放; - 创建文件格式 Reader:
garrow_record_batch_file_reader_new(GARROW_SEEKABLE_INPUT_STREAM(input), &error)将输入流向上转型为GArrowSeekableInputStream后构造 Reader; - 遍历读取:先用
garrow_record_batch_file_reader_get_n_record_batches()获取批数,再对每一批调用garrow_record_batch_file_reader_read_record_batch(reader, i, &error); - 输出列数据:
garrow_record_batch_get_n_columns()/garrow_record_batch_get_column_name()/garrow_record_batch_get_column_data()逐列取出GArrowArray,再按garrow_array_get_value_type()返回的GArrowType分派到garrow_uint8_array_get_value()等类型化取值函数; - 内存管理:每个对象在用完后调用
g_object_unref()释放,符合 GLib 引用计数约定。
对应 API 声明可参见 c_glib/arrow-glib/reader.h:garrow_record_batch_file_reader_new()、garrow_record_batch_file_reader_get_schema()、garrow_record_batch_file_reader_get_n_record_batches()等,其中旧的garrow_record_batch_file_reader_get_record_batch()已标记为废弃,应使用..._read_record_batch()。
从流式格式读取:read-stream.c
与文件格式(首尾含元数据,可随机访问)不同,流格式按顺序串行传输。 c_glib/example/read-stream.c 展示了流式读取范式:garrow_record_batch_stream_reader_new(GARROW_INPUT_STREAM(input), &error)创建流 Reader,然后循环调用garrow_record_batch_reader_read_next(),当返回NULL且无错误时表示流结束:
stream_reader = garrow_record_batch_stream_reader_new(GARROW_INPUT_STREAM(input), &error); reader = GARROW_RECORD_BATCH_READER(stream_reader); while (TRUE) { record_batch = garrow_record_batch_reader_read_next(reader, &error); if (error) { /* 处理读取错误 */ } if (!record_batch) { break; } /* 流结束 */ print_record_batch(record_batch); g_object_unref(record_batch); }扩展类型示例:extension-type.c
c_glib/example/extension-type.c 进一步演示了 GLib 面向对象能力的运用:通过G_DECLARE_DERIVABLE_TYPE+G_DEFINE_TYPE从GArrowExtensionArray与GArrowExtensionDataType派生自定义的 UUID 数组/类型,并实现get_extension_name()、equal()、deserialize()等虚函数——这是把 Arrow 扩展类型机制接入 GI 对象体系的完整样板。
使用方式二:基于 GI 的多语言绑定
除 C 外,Arrow GLib 的 GI 元数据让以下语言可以共享同一套 API 语义:
- Ruby:使用 red-arrow gem(见 ruby/red-arrow/ 目录),基于
gobject-introspectiongem 并增加便捷封装; - Python:使用 PyGObject(注意:Python 场景官方更推荐功能更完整的 PyArrow,而非 Arrow GLib 绑定);
- Lua:使用 LGI(c_glib/example/lua/README.md 提供了
write-file.lua、read-file.lua、write-stream.lua、read-stream.lua四个示例,安装方式为sudo apt install luarocks && sudo luarocks install lgi); - Go:使用 go-gir-generator(同样,Go 场景官方更推荐 go/arrow 原生实现);
- Vala:构建时开启
-Dvapi=true可生成 Vala 的.vapi绑定。
可以看出,Arrow GLib 的价值在于一套 C API 覆盖多语言:对于已有 C 调用栈、或希望以最小成本接入 GI 生态语言的项目,它避免了为每种语言重复实现核心数据结构。
运行单元测试验证安装
c_glib/test/下存放着以 Ruby + test-unit 编写的全部单元测试(覆盖 Array、DataType、Scalar、RecordBatch、Table、计算、文件系统、CUDA、Parquet 等全部模块)。运行测试前需安装 Ruby、gobject-introspectiongem 与test-unitgem:
- Debian/Ubuntu:
sudo apt install -y -V ruby-dev,然后sudo gem install bundler并在c_glib目录执行bundle install; - CentOS 7+:README 给出了基于 rbenv 安装最新版 Ruby 的完整步骤;
- macOS:
(cd c_glib && bundle install)即可。
在构建目录中执行测试(run-test.sh会自动把各模块构建目录加入LD_LIBRARY_PATH/DYLD_LIBRARY_PATH并设置 typelib 目录,见 c_glib/test/run-test.sh):
$ cd c_glib.build $ BUNDLE_GEMFILE=../c_glib/Gemfile bundle exec ../c_glib/test/run-test.sh需要调试时,可用DEBUGGER环境变量指定调试器:
$ DEBUGGER=lldb BUNDLE_GEMFILE=../c_glib/Gemfile bundle exec ../c_glib/test/run-test.sh此外,c_glib/meson.build 已将test/run-test.sh注册为 Meson 的unit test,因此也可以直接用meson test -C c_glib.build触发,测试环境变量(各模块 typelib 目录)由构建系统自动注入。
小结:如何选择与上手
总结而言,Arrow GLib 在 Arrow 生态中的定位是**「面向 GLib/GObject 世界的官方 C 绑定层」**:它把 Arrow C++ 的强大能力封装为标准的 GLib 对象模型,并通过 GObject Introspection 让 Ruby、Lua、Python、Vala 等语言得以低成本复用同一套 API。上手路径也很清晰:先安装与 GLib 匹配的 Arrow C++,再用 Meson 构建安装,然后按需选择 C API(参考 c_glib/example/ 示例)或语言绑定,最后以 Ruby 单元测试验证安装正确性。若你的目标语言已有更成熟的官方实现(如 Python 的 PyArrow、Go 的原生 go/arrow),应优先选择它们;而当你需要 C 接口、Vala 绑定或 GI 生态集成时,Arrow GLib 就是官方推荐的基础设施。
- 数据工程
- 大数据
- 序列化
- 数据分析
【免费下载链接】arrow
Apache Arrow is a multi-language toolbox for accelerated data interchange and in-memory processing
相关推荐
Apache Arrow GLib(C 绑定)指南:基于 GObject Introspection 的 Arrow C++ C API 封装
Apache Arrow GLib(C 绑定)指南:基于 GObject Introspection 的 Arrow C++ C API 封装 Apache A
数据工程数据分析大数据Apache Arrow GLib 实战指南:基于 GObject Introspection 的 C 绑定与多语言桥接
Apache Arrow GLib 实战指南:基于 GObject Introspection 的 C 绑定与多语言桥接 本文以 Apache Arrow 仓库
大数据数据分析数据工程序列化Apache Arrow GLib 实战指南:用 C API 与 GObject Introspection 打通 Arrow C++ 与多语言生态
Apache Arrow GLib 实战指南:用 C API 与 GObject Introspection 打通 Arrow C++ 与多语言生态 Apach
数据工程数据分析大数据
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考