Silu 互操作有两扇门:@export(Silu 函数变成 C 符号,被 C/Rust 宿主链接调用)和 from c import(Silu 声明并调用外部 C 函数)。 配合自举工具链 siluc(一行命令、零 Python),完整用法如下。
# ① 自举管线(推荐):siluc C 驱动 + siluc1 原生编译器 + clang
./siluc program.si -o program # 一行,零 Python,0.13s
# ② 产出可链接对象 + 自动生成 C 头文件
./siluc lib.si -o lib.o --object # 产出 lib.o + lib.o.h
# ③ Python 编译器(开发/调试用)
python -m silu build program.si -o program
# ④ 完全手动、零 Python 的底层管道(会全量编译运行时,慢)
./silu_fe < program.si | ./silu_conv > program.ll
clang -O2 program.ll -o program
siluc 与 siluc1 由 python tools/selfhost_build.py 按源码 mtime 自动重建;首次构建约 25s,之后复用。运行时 .o 缓存在 ~/.cache/silu-runtime/driver/,冷缓存一次性 ~0.4s。
# lib.si
@export
def fib(n: int) -> int:
if n < 2:
return n
return fib(n - 1) + fib(n - 2)
@export
def circle_area(r: float) -> float:
return 3.14159 * r * r
./siluc lib.si -o libfib.o --object # 产出 libfib.o 和 libfib.o.h
生成的头文件(节选):
/* generated by siluc --object */
#include <stdint.h>
#include <stdbool.h>
typedef struct { int32_t tag; void* data; } PObj;
int64_t fib(int64_t);
double circle_area(double);
C 宿主:
#include <stdio.h>
#include "libfib.o.h"
int main(void) {
printf("%lld\n", (long long)fib(24)); // 46368
}
clang -O2 host.c libfib.o -o host && ./host
Rust 宿主:
use std::os::raw::c_longlong;
extern "C" { fn fib(n: c_longlong) -> c_longlong; }
fn main() { unsafe { println!("{}", fib(24)); } }
clang -shared libfib.o -o libfib.dylib
rustc -C opt-level=3 host.rs -o host -C link-arg=-L/dir -C link-arg=-lfib
类型映射:int ↔ int64_t、float ↔ double、bool ↔ bool; 静态标量签名天然就是 C 签名(LLVM 类型系统同构)。动态函数 (含 pyobj 参数/返回)以 PObj* 稳定盒指针传递——C 侧按 tag 读取(0=int 1=float 2=str 4=list 5=dict 6=instance 8=set)。 --object 产物含全部运行时(自包含 .o,宿主无需额外依赖)。
from c import sqrt, floor, pow, strlen
x: float = sqrt(2.0) # 1.4142135623730951
print(floor(3.7)) # 3.0
print(pow(2.0, 10.0)) # 1024.0
s: str = "hello"
print(strlen(s)) # 5
签名);与运行时已有声明同名时自动复用。
str 参数以 const char* 传递(NUL 终止拷贝;C 侧不得释放)。提供 c 模块——同一源码四平面一致。
| 场景 | 验证 |
|---|---|
| C 宿主链接 .o 调 fib/circle_area/safe_mul | ✓(tests/test_c_abi.py) |
| Rust 宿主 extern "C" 调 fib(dylib) | ✓ |
| from c import sqrt/floor/pow 四平面 | ✓(解释器/编译/CPython/parity) |
| strlen 字符串跨边界 | ✓ |
| 动态参数拒绝 | ✓(编译期报错) |
限制:@export 目前作用于静态标量函数(pyobj 函数可导出但 C 侧 需按 PObj 协议操作);extern 无结构体/指针参数支持(按需扩展)。