绑定生成器 (bindgen)¶
Link 提供内置的 link bindgen 工具,可以从 .link 源文件的 export "<lang>" { ... } 块自动生成目标语言的绑定代码,免去手写胶水层的工作。
基本用法¶
| 参数 | 说明 |
|---|---|
--lang / -l |
目标语言: c / python / typescript |
<input.link> |
Link 源文件路径 |
-o / --output |
输出文件路径(默认: stdout) |
--module |
模块名(默认: 输入文件名 stem) |
支持的目标语言¶
| 语言 | --lang 取值 |
输出扩展名 | 输出形式 |
|---|---|---|---|
| C / C++ | c / header / h |
.h |
C 头文件(含 include guard 与 extern "C") |
| Python | python / py / pyi |
.pyi |
Python 类型存根 |
| TypeScript | typescript / ts / dts |
.d.ts |
TypeScript 声明文件 |
示例:一次定义,三处导出¶
examples/link_sdk.link:
export "C" {
fn link_init() -> bool;
fn link_create_room(max_players: u8) -> u32;
fn link_join_room(room_id: u32, player_name: str) -> bool;
fn link_shutdown();
}
export "python" module "link_game" {
fn start_server(port: u16) -> bool;
async fn fetch_state(room_id: u32) -> str;
fn events(room_id: u32) -> stream<i32>;
}
export "typescript" module "link-game-sdk" {
fn createRoom(maxPlayers: u8) -> u32;
async fn fetchState(roomId: u32) -> str;
}
生成 C 头文件¶
输出 examples/link_sdk.h:
#ifndef LINK_LINK_SDK_H
#define LINK_LINK_SDK_H
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
bool link_init(void);
uint32_t link_create_room(uint8_t max_players);
bool link_join_room(uint32_t room_id, const char* player_name);
void link_shutdown(void);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // LINK_LINK_SDK_H
生成 Python 存根¶
输出 examples/link_sdk.pyi:
"""
link_sdk —— Auto-generated by `link bindgen --lang python`
DO NOT EDIT MANUALLY.
Source module: link_game
"""
from typing import AsyncIterable
def start_server(port: int) -> bool: ...
async def fetch_state(room_id: int) -> str: ...
def events(room_id: int) -> AsyncIterable[int]: ...
生成 TypeScript 声明¶
输出 examples/link_sdk.d.ts:
/**
* link_sdk —— Auto-generated by `link bindgen --lang typescript`
* DO NOT EDIT MANUALLY.
* Source module: link-game-sdk
*/
declare module "link_sdk" {
export function createRoom(maxPlayers: number): number;
export function fetchState(roomId: number): Promise<string>;
}
类型映射¶
bindgen 按下表将 Link 类型映射到目标语言:
| Link 类型 | C / C++ | Python | TypeScript |
|---|---|---|---|
bool |
bool |
bool |
boolean |
i8 / i16 / i32 / i64 |
int8_t / int16_t / int32_t / int64_t |
int |
number |
u8 / u16 / u32 / u64 |
uint8_t / ... / uint64_t |
int |
number |
usize |
size_t |
int |
number |
f32 / f64 |
float / double |
float |
number |
str |
const char* |
str |
string |
void / () |
void |
None |
void |
T* |
T* |
int(指针地址) |
number |
stream<T> |
/* stream<T> */ void*(注解) |
AsyncIterable[T] |
AsyncIterable<T> |
命名类型 Foo |
Foo |
Foo |
Foo |
async 函数处理¶
async fn 在不同目标语言中的处理方式:
- C: 注释标记
// async fn ...,签名保持同步形式(C 本身没有 async 概念) - Python: 生成
async def - TypeScript: 返回类型包装为
Promise<T>
多 export 块合并¶
如果源文件中包含多个相同语言的 export 块,bindgen 会自动合并所有声明一起生成:
会合并为一个头文件,包含 first 和 second 两个声明。
语言过滤¶
bindgen 只生成匹配 --lang 的 export 块,其他语言的块会被忽略:
export "C" { fn c_fn() -> bool; }
export "python" { fn py_fn() -> bool; }
export "typescript" { fn ts_fn() -> bool; }
标识符净化¶
如果 Link 中的标识符与目标语言的关键字冲突,bindgen 会自动加下划线后缀:
| Link 标识符 | Python 输出 | TypeScript 输出 |
|---|---|---|
class |
class_ |
class_ |
import |
import_ |
import_ |
function |
function |
function_ |
return |
return_ |
return_ |
错误处理¶
如果源文件中没有匹配语言的 export 块,bindgen 会报错:
(目前 rust 还未作为 --lang 支持,可选项为 c / python / typescript)
当前限制¶
- 不支持生成
struct/enum的目标语言定义(只生成函数声明) - 不支持生成 Python class / TypeScript interface(
export块目前只解析函数签名) - 不支持从 C 头文件反向生成 Link extern 声明(规划中)
- 不支持泛型实例化绑定