尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
在 C 语言中集成 PRQL:prqlc-c 最小示例从编译到运行全解析
后端【免费下载链接】prqlPRQL is a modern language for transforming data — a simple, powerful, pipelined SQL replacement项目地址https://gitcode.com/gh_mirrors/pr/prql点击查看免费下载本篇技术指南以 PRQL 仓库中 minimal-c 示例 为核心讲解如何用gcc与make将 PRQL 编译器prqlc-c C 绑定嵌入 C 程序从构建静态库、编写调用compile()的入口代码到自定义编译选项、解析错误消息与分阶段获取中间表示。读完本文你将掌握一套可直接复制的 C/FFI 集成模板并理解 prqlc-c 在仓库中的完整调用链与内存管理约定。示例概览一个最小的 prqlc-c 集成prqlc-c 绑定 将 PRQL 编译器以 C ABI 的形式暴露出来同时生成静态库.a与动态库.so因此可以被任何支持 FFIForeign Function Interface的语言嵌入例如 Go、C、C、Zig 等。minimal-c示例就是其中最精简的参考实现——它只包含三个文件README.md说明使用场景与运行方式main.c完整的演示程序覆盖默认编译、自定义选项、错误处理与中间结果四类用法Makefile负责先构建 Rust 侧的prqlc-c库再调用gcc链接出可执行文件。整个示例的运行只需要一条命令make run这条命令会先执行build目标编译静态库 编译 C 程序然后运行生成的main.out。构建链路从 Rust 库到 C 可执行文件Makefile 的构建流程Makefile 揭示了完整的构建依赖关系它由两个阶段组成PRQL_PROJECT../../../../.. run: build ./main.out build-prql: cargo build --package prqlc-c --release UNAME_S : $(shell uname -s) LD_FLAGS -L${PRQL_PROJECT}/target/release \ ${PRQL_PROJECT}/target/release/libprqlc_c.a \ -pthread -ldl -lm ifeq ($(UNAME_S),Darwin) LD_FLAGS : $(LD_FLAGS) -framework CoreFoundation endif build: main.c build-prql gcc main.c -o main.out \ -I${PRQL_PROJECT}/prqlc/bindings/prqlc-c \ $(LD_FLAGS)PRQL_PROJECT指向仓库根目录minimal-c位于prqlc/bindings/prqlc-c/examples/minimal-c/向上四级即仓库根。build-prql调用cargo build --package prqlc-c --release在仓库根目录的target/release下产出libprqlc_c.a静态库与libprqlc_c.so动态库。这一产物类型由 prqlc-c/Cargo.toml 中的crate-type [staticlib, cdylib]决定。build用gcc编译main.c头文件搜索路径-I指向prqlc/bindings/prqlc-c即 prqlc.h 所在目录并链接静态库及系统依赖-pthread -ldl -lm。macOS 下额外需要-framework CoreFoundation这与 Rust 运行时在 macOS 上的链接需求有关Makefile 通过UNAME_S判断并自动追加。该 Makefile 也被 prqlc-c README 引用为标准链接参数的权威来源若使用其他构建系统可按同样方式指向target/release下的libprqlc_c.a例如 Go 的CGO_LDFLAGS-L/path/to/target/release -lprqlc_c -pthread -ldl -lm。另外 Makefile 还提供了一个valgrind目标用于在内存检查器下运行示例配合下文讲到的result_destroy内存释放约定可以验证程序没有泄漏。C 侧 API 面核心类型与函数头文件 prqlc.h 由 cbindgen 自动生成生成命令task build-prqlc-c-header配置见 cbindgen.toml它完整定义了 FFI 接口。示例中用到的核心类型如下类型作用CompileResult编译结果包含output生成的 SQL/JSON 字符串、messages消息数组与messages_len消息条数Message单条编译消息含code机器可读错误码、reason错误文本、hint修复建议、display带注解的源码片段、span/location错误位置Options编译选项含format、target、signature_comment三个字段MessageKind消息类型枚举目前仅实现ErrorWarning与Lint已预留公开的入口函数共五个compile(prql_query, options)一键完成 PRQL → SQL 的完整编译prql_to_pl(prql_query)PRQL → PL解析树以 JSON 输出pl_to_rq(pl_json)PL → RQ关系查询中间表示以 JSON 输出rq_to_sql(rq_json, options)RQ → SQLresult_destroy(res)释放CompileResult占用的全部内存。从 src/lib.rs 的实现可以看到compile本质上是后三个函数的串联封装——它在 Rust 侧依次调用prqlc::prql_to_pl、prqlc::pl_to_rq、prqlc::rq_to_sql并且省去了中间 JSON 的序列化/反序列化开销。编写 main.c四类核心用法逐行解读示例程序 main.c 结构清晰依次演示了四种典型场景。1. 默认选项编译char *prql_query; prql_query from albums | select {album_id, title} | take 3; CompileResult res; // default compile option res compile(prql_query, NULL); print_result(res); if (res.messages_len ! 0) return 1; result_destroy(res);把NULL作为第二个参数传给compile即使用默认编译选项。程序随后检查messages_len若不为 0 则说明编译失败返回非零退出码。成功后调用result_destroy释放资源。这里体现的是 prqlc-c 最重要的两条约定任何返回CompileResult的函数都必须配套调用一次result_destroy且不能手动释放其中任何字段详见 prqlc.h 中result_destroy的 Safety 注释以及 lib.rs 中对字符串、向量、结构体逐项回收的实现。2. 自定义编译选项Options opts; opts.format false; opts.signature_comment false; opts.target sql.mssql; res compile(prql_query, opts); print_result(res);Options结构体包含三个字段默认值见 prqlc.hformat默认true是否将生成的 SQL 通过格式化器美化——拆分多行、调整缩进与空格target默认sql.any目标 SQL 方言。sql.any表示从查询头target查询头注释中提取方言显式传入如sql.mssql则强制指定signature_comment默认true是否在生成的 SQL 末尾追加编译器签名注释。target的解析逻辑在 prqlc/prqlc/src/lib.rs字符串必须以sql.为前缀其后跟方言名或any支持的全部方言在 dialect.rs 的Dialect枚举中定义包括Ansi、BigQuery、ClickHouse、DuckDb、Generic、MsSql、MySql、Postgres、SQLite、Snowflake因此target也可以取sql.duckdb、sql.postgres、sql.sqlite等。非法值会被转换为错误消息返回。底层转换见 lib.rsRust 侧将 C 的Options转为prqlc::Options其中target为NULL或空串时统一回退为sql.any。3. 错误处理// error handling res compile(from album | select {album_id} | select {title}, NULL); print_result(res); if (res.messages_len 0) return 1; result_destroy(res);这段代码故意传入语义有误的 PRQLalbum在from后被当作表使用紧接着又被当作列名select属于命名/类型冲突场景验证错误路径编译失败时CompileResult.messages_len大于 0。第二个错误样例let a (from album)同样用于触发错误分支。print_result展示了读取消息字段的正确姿势void print_result(CompileResult res) { printf(---- [ Compiled with %zu errors ]----\n, res.messages_len); for (size_t i 0; i res.messages_len; i) { Message const *e res.messages[i]; if (e-display ! NULL) { printf(%s, *e-display); } else if (e-code ! NULL) { printf([%s] Error: %s\n, *e-code, e-reason); } else { printf(Error: %s, e-reason); } } if (*res.output \0) { printf(Output: empty\n\n); } else { printf(Output:\n%s\n\n, res.output); } }优先打印display带源码注解与定位的错误展示信息最丰富其次打印code与reason否则只打印reason。同时编译失败时output为空串示例据此区分输出为空与有输出两种情况。4. 分阶段编译获取中间表示// intermediate results res prql_to_pl(prql_query); print_result(res); res2 pl_to_rq(res.output); result_destroy(res); print_result(res2); result_destroy(res2);最后一段演示了调试与集成非常有用的分阶段能力prql_to_pl返回 PRQL 的解析树PLpl_to_rq再把它转换为关系查询中间表示RQ两者都以 JSON 字符串放在CompileResult.output中。注意这里先用res2接收pl_to_rq的结果然后才result_destroy(res)释放第一个结果——在把res.output作为入参传给下一个函数之前不能提前释放否则会访问已释放内存。示例还顺带印证了每个返回CompileResult的函数都必须配套一次result_destroy的规则。运行与验证在仓库根目录执行make run或进入prqlc/bindings/prqlc-c/examples/minimal-c/后执行预期输出依次为默认编译from albums | select {album_id, title} | take 3生成的 SQL关闭格式化、去掉签名注释、强制sql.mssql方言后的 SQL可观察到与默认输出的差异例如方言特有的语法与单行输出两段错误 PRQL 的编译消息Compiled with N errors 带注解的错误展示prql_to_pl与pl_to_rq得到的 JSON 中间表示。若改用make valgrind运行Valgrind 会检查每次compile/prql_to_pl/pl_to_rq后调用的result_destroy是否完整释放了 FFI 层分配的内存。同类参考实现还包括 minimal-cpp使用 cbindgen 生成的 C 头文件prqlc.hpp调用方式几乎一致见 main.cpp与 minimal-zig通过cImport引入prqlc.h它们共享同一套 FFI 面。小结minimal-c示例为在 C乃至任何支持 FFI 的语言中嵌入 PRQL 编译器提供了最小可行模板。其要点可归纳为以cargo build --package prqlc-c --release产出静态库用gcc -Iprqlc/bindings/prqlc-c链接通过compile(prql_query, options)完成端到端编译其中options NULL即默认配置Options三字段分别控制格式化、方言与签名注释通过messages_len与Message各字段完成错误诊断通过prql_to_pl/pl_to_rq获取中间表示最后务必为每个CompileResult调用一次result_destroy。深入阅读 prqlc.h 与 lib.rs 可获得完整 FFI 契约这为扩展自己的宿主语言绑定提供了清晰的起点。赞分享后端【免费下载链接】prqlPRQL is a modern language for transforming data — a simple, powerful, pipelined SQL replacement项目地址https://gitcode.com/gh_mirrors/pr/prql点击查看免费下载相关推荐使用 Rerun C SDK 编写最小 C 示例从编译链接到运行 Viewer使用 Rerun C SDK 编写最小 C 示例从编译链接到运行 Viewer 本篇技术指南以 examples/c/minimal https://link数据可视化3D渲染数据分析在 Android NDK 中集成预编译第三方 C/C 库hello-libs 示例深度解析在 Android NDK 中集成预编译第三方 C/C 库hello libs 示例深度解析 导读 本篇文章围绕 Android NDK Samples示例工程移动开发Wasmtime 多语言 API 示例指南从 Rust/C/C 示例到嵌入实战Wasmtime 多语言 API 示例指南从 Rust/C/C 示例到嵌入实战 导读 examples 目录是 Wasmtime 官方提供的、以多语言 A语言运行时JIT编译编译器创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

从 0 到 1 构建 AI 营销文案 SaaS:基于 Supabase + Stripe 的完整实战项目指南(Easy-Vibe Stage 2)

从 0 到 1 构建 AI 营销文案 SaaS:基于 Supabase + Stripe 的完整实战项目指南(Easy-Vibe Stage 2)

教程文档 【免费下载链接】easy-vibe 从 0 到 1 学会 vibe coding,项目制学习 项目地址: https://gitcode.com/datawhalechina/easy-vibe 点击查看 免费下载 本篇指南是 Easy-Vibe 课程 Stage 2 的综合实战项目:基于一份真实 PRD&#xff0c…

📅 2026/9/24 1:53:52
OOMWOO 驱动轮模块实测规格全解析:Roborock S5 Max 系列电机、霍尔编码器与减速箱逆向工程

OOMWOO 驱动轮模块实测规格全解析:Roborock S5 Max 系列电机、霍尔编码器与减速箱逆向工程

智能硬件机器人嵌入式物联网 【免费下载链接】oomwoo Open-source vacuum robot cleaner 项目地址: https://gitcode.com/gh_mirrors/oo/oomwoo 点击查看 免费下载 本文基于 contributions/part-specs/IKsares/drive-wheel/README.md 整理。该文档是对一个后市场&a…

📅 2026/9/24 1:53:52
论文降重实用技巧分享 高效降低重复率的可行方法汇总

论文降重实用技巧分享 高效降低重复率的可行方法汇总

每次找到心仪的外国文献,却被付费墙冷冷地挡在外面,是不是感觉科研的热情瞬间被浇灭?作为学生党,我太懂这种无力感了。但好消息是,通过几个合法且免费的“通道”和技巧,我们完全能实现“文献自由”。今天分…

📅 2026/9/24 1:53:52
MORE NEWS

更多资讯

📰

Dopamine 实验统计汇总实战:深入解析 colab.utils.summarize_data 逐迭代数据聚合

机器学习深度学习 【免费下载链接】dopamine Dopamine is a research framework for fast prototyping of reinforcement learning algorithms. 项目地址: https://gitcode.com/gh_mirrors/do/dopamine 点击查看 免费下载 导读:本文围绕 Dopamine 强化…

📰

EMQX MQTT 桥接陈旧连接状态修复解析:从「假 Connected」到真实健康检查与自动重连

后端物联网消息队列通信 【免费下载链接】emqx The most scalable and reliable MQTT broker for AI, IoT, IIoT and connected vehicles 项目地址: https://gitcode.com/gh_mirrors/em/emqx 点击查看 免费下载 本文围绕 EMQX 开源仓库中 changes/ee/fix-15603.en.…

📰

CAD软件有哪些?建筑、机械、协同各领域代表软件梳理

CAD(Computer Aided Design,计算机辅助设计)软件是工程设计领域不可或缺的核心工具,广泛应用于建筑设计、机械制造、土木工程、电子电气、产品研发等众多行业。其核心目的是通过数字化手段提升设计效率、保证设计精度、便于协同与…

📰

AI陪伴机器人DTO参数校验-把脏数据拦在门口

07-DTO参数校验-把脏数据拦在门口系列:AI 伙伴(AI-Partner)——具身智能陪伴机器人 数据接口部署与二次开发篇(07/12)一、为什么校验要放在"门口" 先说个真实场景:你在前端页面上提交一条健康记…

📰

海信电视秋季新品打出王炸,双7旗舰首发,RGB-Mini LED电视体验常用常新

9月23日,2026海信电视召开秋季新品发布会,正式推出全新一代RGB-Mini LED影像旗舰U7T Pro、性能旗舰E7S Pro两大双7旗舰新品,一次性落地六大行业首发技术,从背光硬件、屏幕素质、专属画质到智能系统全方位革新,彻底改写…

📰

Python coding + ML + general coding ability

# Linked List(链表)面试知识体系与记忆模板> 核心原则:**Array 用 index;Linked List 用 pointer。**>> 链表题的核心不是“访问元素”,而是“移动和重新连接节点”。---## 1. 基本结构texthead↓[1] → [2]…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬