Appearance
互操作设计
目标
Qlang 要想在真实工程里落地,必须天然支持和已有原生生态协作。这里的关键不是“能不能链接”,而是:
- 调用规则是否稳定
- 边界上的所有权是否明确
- 构建系统是否好用
- 调试和诊断是否能跟上
总策略
结论一:C ABI 是互操作底座
无论目标是 C、C++ 还是 Rust,第一层稳定互操作都围绕 C ABI 展开。原因:
- ABI 稳定、平台可控
- LLVM 生成对象文件与链接流程成熟
- 能作为其他语言接入 Qlang 的最小公共层
结论二:C++ 必须分阶段推进
直接完整支持 C++ ABI、模板、异常、名称修饰和对象模型,复杂度极高。正确策略不是一开始宣称“全面互通”,而是:
- P0:通过 C shim 接入 C++ 库
- P1:支持常见类、命名空间、静态函数、简单方法绑定生成
- P2:再评估异常、模板实例和更多 ABI 细节
结论三:Rust 先走稳定边界,再谈更深整合
Rust 互操作优先方案:
- 使用
extern "C"暴露稳定接口 - 使用
bindgen/cbindgen风格工具生成桥接层 - 通过
repr(C)和显式生命周期转换包装复杂类型
后续如果需要更深整合,再研究读取 Rust 元数据或更直接的符号协作。
语言层设计
建议提供清晰的 FFI 语法:
rust
extern "c" {
fn strlen(ptr: *const U8) -> USize;
}
extern "c" pub fn q_add(left: I32, right: I32) -> I32;边界规则:
- FFI 声明必须显式 ABI
- 原始指针、裸句柄、未验证布局放入
unsafe - 可自动生成安全包装层
构建系统设计
ql 统一 CLI 应支持:
- 编译本地 C 文件
- 调用系统编译器或 clang
- 链接静态库和动态库
- 生成头文件和桥接代码
- 为 Rust/C++ 示例工程创建模板
调试与诊断
互操作体验不仅是“编译通过”,还包括:
- FFI 边界的布局检查
- ABI 不匹配报错
- 符号缺失诊断
- unsafe 调用点的追踪
- 与 lldb / gdb 的调试信息配合
推荐顺序
- 先把 C FFI 做成一等能力
- 用 C ABI 打通 Rust 互操作
- 用 shim 稳定支持 C++ 库接入
- 最后再扩展更直接的 C++ 能力
如果顺序反过来,项目极大概率会陷入“演示很酷、工程不可用”的状态。