Apache Arrow GLib 实战指南用 C API 与 GObject Introspection 打通 Arrow C 与多语言生态【免费下载链接】arrowApache Arrow is a multi-language toolbox for accelerated data interchange and in-memory processing项目地址: https://gitcode.com/gh_mirrors/arrow12/arrowApache Arrow GLib 是 Apache Arrow 项目中面向 C 语言及 GLib/GObject 生态的一层官方绑定库它在 Arrow C 之上提供了一套完整的 C API并借助 GObject Introspection 机制让 Ruby、Python、Lua、Go 等语言可以在运行时动态生成绑定直接复用 Arrow C 的全部能力。本文以 c_glib/README.md 为主线结合仓库中的示例源码、Meson 构建配置与单元测试脚本系统讲解 Arrow GLib 的架构组成、从源码构建的完整流程、C API 与多语言绑定的使用方法、测试运行方式以及常见构建问题的排查方案。读完本文你将具备从零构建 Arrow GLib、编写 C 示例程序并接入任意 GObject Introspection 支持语言的能力。Arrow GLib 是什么为 Arrow C 提供一层 GLib/C 绑定Arrow GLib 的本质是一个包装库wrapper library其定位在 c_glib/README.md 开头有明确说明它基于 Arrow C 实现对外提供 C API。这意味着 C 语言开发者可以直接获得一份面向 Arrow 列式内存格式、计算、文件读写等能力的完整 C 接口而不必直接面对 C 的模板与对象模型。更重要的是Arrow GLib 原生支持 GObject IntrospectionGI。GI 会为已安装的库生成描述类型系统与函数的 typelib 与 GIR 元数据文件任何实现了 GI 加载器的语言都能据此在运行时或编译时创建语言绑定。原文档给出了一个非常直观的 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)会读取安装好的 Arrow typelib把 Arrow C 中的arrow::BooleanArray等类型一一映射为 Ruby 对象。在 Ruby 场景下官方建议直接使用基于 gobject-introspection gem 构建的 red-arrow gem它在原始动态绑定之上补充了大量便捷特性。架构概览arrow-glib 核心库与各功能子模块Arrow GLib 并非单一库而是以arrow-glib为核心的子模块集合。从 c_glib/arrow-glib/arrow-glib.h 的头文件包含关系可以看到核心库覆盖的能力面数组与构建器array.h、array-builder.h、数据类型data-type.h、type.h、计算compute.h、表达式expression.h、Schema/RecordBatch/Tableschema.h、record-batch.h、table.h、文件系统file-system.h、local-file-system.h、IPC 读写reader.h、writer.h、ipc-options.h以及流与内存映射输入输出等。围绕核心库仓库中还包含多个按功能划分的 GLib 包装子模块子模块目录功能定位c_glib/arrow-glib核心库覆盖数组、数据类型、Schema、Table、IPC、文件系统、计算等c_glib/parquet-glibParquet 文件读写、Arrow 文件读写器与元数据、统计信息c_glib/arrow-dataset-glibDataset API数据集工厂、Scanner、Fragments、分区Partitioningc_glib/arrow-flight-glibFlight RPC 客户端与服务端client/serverc_glib/arrow-flight-sql-glibFlight SQL 客户端与服务端c_glib/arrow-cuda-glibCUDA 设备内存支持c_glib/gandiva-glibGandiva 表达式求值表达式、过滤器、投影Projector、函数注册表这一模块化布局与 c_glib/test/run-test.sh 中测试模块列表一一对应也决定了安装时各个共享库如libarrow-glib、libparquet-glib分别提供独立 API。安装 Arrow GLib原文档明确指出推荐直接使用发行版提供的包如果选择自行构建构建工具链为 Meson Ninja。无论哪种方式Arrow GLib 都依赖先安装好的 Arrow C。使用发行版包各操作系统与包管理器下的二进制包可通过官方安装文档获取按对应平台执行安装命令即可无需自行编译。从源码构建用户视角普通用户应使用官方发布的源码归档进行构建。以 12.0.0 版本为例替换版本号为实际使用版本$ wget https://www.apache.org/dyn/closer.lua?actiondownloadfilenamearrow/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.0在构建 Arrow GLib 之前必须先构建并安装 Arrow C详见 Arrow C 的构建文档。macOSHomebrew 环境需先安装依赖$ brew bundle --filec_glib/Brewfile $ meson setup c_glib.build c_glib --buildtyperelease $ meson compile -C c_glib.build $ sudo meson install -C c_glib.build其他平台$ meson setup c_glib.build c_glib --buildtyperelease $ meson compile -C c_glib.build $ sudo meson install -C c_glib.build这里的meson setup c_glib.build c_glib表示在c_glib.build目录中配置源码目录c_glib--buildtyperelease对应发布构建meson compile执行 Ninja 编译meson install完成安装。从源码构建开发者视角面向开发者的构建额外需要 GTK-Doc 与 GObject Introspection用于生成 API 文档与绑定元数据。各平台依赖安装命令如下Debian GNU/Linux 或 Ubuntu$ sudo apt install -y -V gtk-doc-tools libgirepository1.0-dev meson ninja-buildCentOS 7$ sudo yum install -y gtk-doc gobject-introspection-devel ninja-build $ sudo pip3 install mesonCentOS 8 及以后$ sudo dnf install -y --enablerepopowertools gtk-doc gobject-introspection-devel ninja-build $ sudo pip3 install mesonmacOSHomebrew$ brew bundle --filec_glib/Brewfile然后执行开发者构建macOS 需要先设置 XML 目录以支持文档生成$ XML_CATALOG_FILES$(brew --prefix)/etc/xml/catalog $ meson setup c_glib.build c_glib -Dgtk_doctrue $ meson compile -C c_glib.build $ sudo meson install -C c_glib.build其他平台meson setup的简写形式meson c_glib.build c_glib同样可用$ meson c_glib.build c_glib -Dgtk_doctrue $ meson compile -C c_glib.build $ sudo meson install -C c_glib.build注意在 macOS 上构建 Arrow GLib 时默认会链接 Homebrew 安装的 Arrow C当 GLib 层与 C 库改动不一致时可能产生构建失败。此时应通过--cmake-prefix-path显式指定本地构建的 Arrow C 安装前缀$ meson setup c_glib.build c_glib --cmake-prefix-path${arrow_cpp_install_prefix} -Dgtk_doctrue关键 Meson 构建选项从 c_glib/meson_options.txt 可以看到 Arrow GLib 提供的全部构建开关理解它们有助于针对不同场景定制构建选项类型与默认值说明arrow_cpp_build_dirstring默认空使用尚未安装的 Arrow C 构建目录进行构建arrow_cpp_build_typestring默认release传给 Arrow C 的-DCMAKE_BUILD_TYPE取值docboolean默认false构建文档已被gtk_doc取代标注为 deprecatedgtk_docboolean默认false构建文档需要 Meson 0.63.0 或更高版本source_referencestring默认main文档中源码链接指向的 revision/branch/tagvapiboolean默认false构建 Vala API供 Vala 绑定使用例如仅编译而不生成文档时保持默认即可若要在未安装 Arrow C 的开发环境中联调可传入-Darrow_cpp_build_dir/path/to/cpp.build。使用 Arrow GLibArrow GLib 的使用分两条路线C 语言直接使用 C API其他语言通过 GObject Introspection 绑定使用。通过 C API 使用C 开发者只需包含arrow-glib/arrow-glib.h头文件并链接libarrow-glib。安装后API 参考文档位于/usr/local/share/gtk-doc/html/arrow-glib/目录若meson指定了--prefix目录会随之变化。仓库的 c_glib/example 目录提供了可直接参考的 C 示例示例同时会随构建安装到数据目录下的arrow-glib/example其中build.c演示用GArrowInt32ArrayBuilder构建数组并读取。核心流程是先garrow_int32_array_builder_new()创建构建器多次garrow_int32_array_builder_append_value()追加值每次调用传入GError **检查失败最后garrow_array_builder_finish()收尾得到GArrowArray再通过garrow_array_get_length()与garrow_int32_array_get_value()逐元素读取并打印。read-file.c演示读取 Arrow 文件格式File Format即/tmp/batch.arrow这类随机访问文件。调用链为garrow_memory_mapped_input_stream_new()打开内存映射输入流 →garrow_record_batch_file_reader_new()创建文件读取器 →garrow_record_batch_file_reader_get_n_record_batches()与garrow_record_batch_file_reader_read_record_batch()逐批读取 → 用garrow_record_batch_get_n_columns()、garrow_record_batch_get_column_name()、garrow_record_batch_get_column_data()遍历列并打印。read-stream.c演示读取 Arrow 流格式Streaming Format即/tmp/stream.arrow。与文件格式的区别在于使用garrow_record_batch_stream_reader_new()创建流读取器并通过garrow_record_batch_reader_read_next()循环读取直到返回NULL表示流结束。extension-type.c演示自定义扩展类型Extension Type通过继承GArrowExtensionArray与GArrowExtensionDataType实现一个 UUID 示例扩展类型。其余还有receive-network.c、send-network.c展示网络传输场景。C 示例中反复出现的模式值得注意所有可能失败的操作都通过GError *error传递错误返回值非空即成功、为空则需打印并释放error所有 GObject 对象在使用结束后都调用g_object_unref()释放。这正是 GLib 生态的标准资源管理方式。基于 GObject Introspection 的多语言绑定Arrow GLib 支持所有实现了 GObject Introspection 的语言。原文档按语言给出了官方推荐方案Ruby应使用 red-arrow gem基于 gobject-introspection gem 构建在原始绑定之上增加便捷特性。Python应使用 PyGObject注意Python 场景官方建议优先选择 PyArrow 而非 Arrow GLib。Lua应使用 LGI示例见 c_glib/example/lua 目录。Go应使用 Go-gir-generator注意Go 场景官方建议优先选择 Apache Arrow for Go 而非 Arrow GLib。以 Lua/LGI 为例read-file.lua 展示了与 C 版本完全对应的读文件逻辑lgi.Arrow加载绑定Arrow.MemoryMappedInputStream.new(input_path)打开输入流Arrow.RecordBatchFileReader.new(input)创建读取器随后循环reader:read_record_batch(i)并逐列get_column_name/get_column_data/get_value打印最后input:close()。而 write-file.lua 则展示了写入侧构造 10 个Arrow.Fielduint8 到 double 全类型组成Arrow.Schema.new(fields)Arrow.FileOutputStream.new(output_path, false)打开输出Arrow.RecordBatchFileWriter.new(output, schema)创建写入器再用各类型ArrayBuilder的append/finish构建列并写入。vala 目录还提供了 Vala 语言的对应示例read-file.vala、read-stream.vala、write-file.vala、write-stream.vala配合-Dvapitrue构建选项即可生成 Vala 绑定。运行时动态绑定原理之所以各语言能共享同一套 API关键在于 GObject Introspection 的两类产物GIR 文件XML 格式描述类型、函数、信号与typelib 二进制文件。Arrow GLib 在meson install阶段会为每个子模块arrow-glib、parquet-glib 等生成并安装 typelib语言侧加载器如 Ruby 的 gobject-introspection gem、Lua 的 LGI、Python 的 PyGObject解析 typelib 后即可在运行时把garrow_*函数与GArrow*对象映射为对应语言的对象与方法。这就是一份 C 库多语言复用的机制来源。运行单元测试Arrow GLib 自带单元测试可用于验证安装是否正确。运行测试前需要准备 Ruby、gobject-introspection gem 与 test-unit gem。Debian GNU/Linux 或 Ubuntu$ sudo apt install -y -V ruby-dev $ sudo gem install bundler $ (cd c_glib bundle install)CentOS 7 及以后通过 rbenv 安装 Ruby$ sudo yum install -y git $ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv $ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build $ echo export PATH$HOME/.rbenv/bin:$PATH ~/.bash_profile $ echo eval $(rbenv init -) ~/.bash_profile $ exec ${SHELL} --login $ sudo yum install -y gcc make patch openssl-devel readline-devel zlib-devel $ latest_ruby_version$(rbenv install --list 21 | grep ^[0-9] | tail -n1) $ rbenv install ${latest_ruby_version} $ rbenv global ${latest_ruby_version} $ gem install bundler $ (cd c_glib bundle install)macOSHomebrew$ (cd c_glib bundle install)依赖解析由 c_glib/Gemfile 管理其中固定了test-unit与gobject-introspection要求不低于 4.1.1两个 gem。依赖就绪后在构建目录中运行测试$ cd c_glib.build $ BUNDLE_GEMFILE../c_glib/Gemfile bundle exec ../c_glib/test/run-test.sh从 run-test.sh 的实现可以看到测试脚本的工作机制它会为 arrow-glib、parquet-glib、arrow-dataset-glib 等全部 7 个模块设置LD_LIBRARY_PATH/DYLD_LIBRARY_PATH与GI_TYPELIB_PATH指向各模块的构建目录随后执行ninja增量构建并调用 Ruby 测试入口 run-test.rb。测试覆盖矩阵非常广c_glib/test 下包含数百个test-*.rb用例覆盖数组、数据类型、Scalar、构建器、计算cast、filter、sort、take 等、IPC 读写、文件系统、各子模块功能。需要调试时可通过DEBUGGER选项挂接调试器$ DEBUGGERlldb BUNDLE_GEMFILE../c_glib/Gemfile bundle exec ../c_glib/test/run-test.shrun-test.sh支持gdb与lldb两种调试器gdb 通过--args传入参数lldb 则先设置DYLD_LIBRARY_PATH再启动。若只想运行测试而跳过 ninja 重建可设置BUILDno。常见构建与测试问题排查原文档整理了四个高频问题这里结合仓库细节逐一说明构建失败/usr/bin/ld: cannot find -larrow链接器找不到libarrow原因是 Arrow C 尚未安装。解决在 Arrow C 构建目录执行make install在 Linux 上还需要运行sudo ldconfig刷新动态链接器缓存。构建失败unable to load http://docbook.sourceforge.net/release/xsl/current/html/chunk.xslmacOS 上生成文档时无法加载 DocBook XSL需要显式指定本机 XML 目录$ export XML_CATALOG_FILES$(brew --prefix)/etc/xml/catalog构建失败Symbol not found ... libsource-highlight.4.dylibmacOS 上由source-highlight版本过旧引起典型报错为dyld: Symbol not found: __ZN5boost16re_detail_...解决方式是升级依赖$ brew upgrade source-highlight测试失败Failed to load shared library ... referenced by the typelib: dlopen(...): dependent dylib rpath/... not foundmacOS 上运行测试时 typelib 依赖的 dylib 找不到根因是 Arrow C 使用了rpath安装名Arrow GLib 不支持rpath。解决重新以-DARROW_INSTALL_NAME_RPATHOFF构建 Arrow C$ cmake -S cpp -B cpp.build -DARROW_INSTALL_NAME_RPATHOFF ... $ cmake --build cpp.build $ sudo cmake --build cpp.build --target install小结Arrow GLib 是 Apache Arrow 多语言战略中的关键一环通过一套 GLib/C 绑定与 GObject Introspection 元数据把 Arrow C 的列式内存格式、计算内核、Parquet/Dataset/Flight 等能力开放给 C 及 Ruby、Python、Lua、Go、Vala 等众多语言。从本仓库的 c_glib 目录出发你可以按 README.md 中的流程用 Meson/Ninja 从源码构建并安装参考 c_glib/example 中的 C、Lua、Vala 示例快速上手读写 Arrow 文件与流使用 c_glib/test/run-test.sh 验证安装正确性并依据常见构建问题一节解决跨平台构建中的典型坑点。对希望以非 C 语言使用 Apache Arrow 的开发者而言Arrow GLib 提供了一条统一、稳定且可动态扩展的接入路径。【免费下载链接】arrowApache Arrow is a multi-language toolbox for accelerated data interchange and in-memory processing项目地址: https://gitcode.com/gh_mirrors/arrow12/arrow创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
