在 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),仅供参考

相关新闻

STM32H7 OSPI+PSRAM内存映射实战:MPU配置与时序避坑指南

STM32H7 OSPI+PSRAM内存映射实战:MPU配置与时序避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 1:51:30 阅读更多 →
PaddleHub vgg13_imagenet 图像分类模块:基于 VGG13 与 ImageNet-2012 的安装、预测 API 与实现原理详解

PaddleHub vgg13_imagenet 图像分类模块:基于 VGG13 与 ImageNet-2012 的安装、预测 API 与实现原理详解

人工智能大模型微调模型推理服务 【免费下载链接】PaddleFormers PaddleFormers is an easy-to-use library of pre-trained large language model zoo based on PaddlePaddle. 项目地址: https://gitcode.com/gh_mirrors/pa/PaddleFormers 点击查看 免费下载 导读…

2026/9/24 1:51:30 阅读更多 →
EMC设计全链路实战:从原理图到量产的硬核避坑指南

EMC设计全链路实战:从原理图到量产的硬核避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 1:51:30 阅读更多 →

最新新闻

SSM计算机毕设之基于 SSM 的线上课程学习考评系统的设计与实现 基于 SSM 的网络化教育视频服务系统(完整前后端代码+说明文档+LW,调试定制等)

SSM计算机毕设之基于 SSM 的线上课程学习考评系统的设计与实现 基于 SSM 的网络化教育视频服务系统(完整前后端代码+说明文档+LW,调试定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/9/24 4:05:53 阅读更多 →
【SSM课程设计/毕业设计】基于 SSM 的在线教学内容管理系统的设计与实现 基于 SSM 的教育培训视频阅览系统的设计与实现【附源码、数据库、万字文档】

【SSM课程设计/毕业设计】基于 SSM 的在线教学内容管理系统的设计与实现 基于 SSM 的教育培训视频阅览系统的设计与实现【附源码、数据库、万字文档】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/9/24 4:05:53 阅读更多 →
Prisma CLI 数据导出实战:`prisma export` 命令详解与底层实现原理

Prisma CLI 数据导出实战:`prisma export` 命令详解与底层实现原理

后端数据库GraphQL 【免费下载链接】prisma1 💾 Database Tools incl. ORM, Migrations and Admin UI (Postgres, MySQL & MongoDB) [deprecated] 项目地址: https://gitcode.com/gh_mirrors/pr/prisma1 点击查看 免费下载 本文围绕 Prisma 1.x 的 …

2026/9/24 4:05:53 阅读更多 →
电流采样电阻PCB布局:三种开尔文接法对比与0.1%精度实现

电流采样电阻PCB布局:三种开尔文接法对比与0.1%精度实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 4:05:53 阅读更多 →
【SSM毕业设计】基于 SSM 的线上教学资源共享系统的设计与实现 基于 SSM 的学生视频学习管理系统(源码+文档+远程调试,全bao定制等)

【SSM毕业设计】基于 SSM 的线上教学资源共享系统的设计与实现 基于 SSM 的学生视频学习管理系统(源码+文档+远程调试,全bao定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/9/24 4:05:53 阅读更多 →
ESP32 上跑 WebAssembly:运行时如何把字节码翻译给 CPU

ESP32 上跑 WebAssembly:运行时如何把字节码翻译给 CPU

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 4:04:53 阅读更多 →

日新闻

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为…

2026/9/24 0:00:19 阅读更多 →
单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

简介:一份基于单细胞RNA测序数据的细胞类型注释算法研究Python毕业设计源码,针对计算机相关专业正在做毕设或需要项目实战的学习者,可用于课程设计与期末大作业。项目代码完整、经导师指导评审通过,可直接运行,覆盖数据…

2026/9/24 0:00:19 阅读更多 →
C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

第一次在项目里被反射卡住,是在一个老旧的WinForms模块里:几十个类依赖PropertyChanged通知,运行时反射读属性、发通知,每次启动慢半拍不说,一上.NET Native/AOT裁剪模式几乎全面崩盘。后来我把这段逻辑全部改成C#源生…

2026/9/24 0:00:19 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/23 4:55:02 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/23 4:49:06 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/23 9:53:41 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/23 9:53:40 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/23 9:53:40 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/23 9:53:40 阅读更多 →