dlopen 加载共享库并返回带类型化符号的 Library 实例。
语法
function dlopen<Fns extends Record<string, FFIFunction>>(
libName: string,
defs: Fns,
): Library<Fns>;
示例
import { dlopen, FFIType } from 'arkffi';
const lib = dlopen('libffi_target.so', {
add: { args: [FFIType.double, FFIType.double], returns: FFIType.double },
compute: { args: [FFIType.int32, FFIType.double, FFIType.CString], returns: FFIType.double },
});
lib.symbols.add(2.0, 3.0);
lib.symbols.compute(0, 4.0, 'square');
lib.close();
参数
| 参数 | 类型 | 说明 |
|---|---|---|
libName | string | .so 库的路径或名称 |
defs | Record<string, FFIFunction> | 函数名到类型定义的映射 |
FFIFunction
interface FFIFunction {
args: (string | StructSchema)[]; // 参数类型编码,支持 StructSchema
returns: string | StructSchema; // 返回类型编码,支持 StructSchema
threadsafe?: boolean; // 用于 JSCallback 定义
}
结构体类型支持
args 和 returns 除了接受 FFIType.* 字符串,还可传入 StructSchema 实例,用于在寄存器中传递的小型 HFA 结构体。
const Complex = Struct({ real: FFIType.double, imag: FFIType.double });
const lib = dlopen('libfft.so', {
complex_add: {
args: [Complex, Complex], // 展开为 4 个 double
returns: Complex, // 编码为返回 buffer ← 返回指针
},
});
let a = Complex.create({ real: 1, imag: 2 });
let b = Complex.create({ real: 3, imag: 4 });
let ptr: number = lib.symbols.complex_add(a, b);
let result = Complex.fromPtr(ptr);
console.log(result.real, result.imag); // 4, 6
defineFunction(handle, 'complex_add', 'dddd', '2')
↑ StructSchema 展开为字段类型
调用时:
ArrayBuffer → 解包为 [1, 2, 3, 4] → NAPI
NAPI 返回 buffer → ffi.ptr(buf) → 指针返回给用户
异步调用
每个symbols 下的函数都挂载了 .async 方法,用于在工作线程上非阻塞调用:
const Complex = Struct({ real: FFIType.double, imag: FFIType.double });
const lib = dlopen('libfft.so', {
complex_mul: { args: [Complex, Complex], returns: Complex },
});
let a = Complex.create({ real: 4, imag: 1 });
let b = Complex.create({ real: 3, imag: 3 });
lib.symbols.complex_mul.async(a, b).then((ptr: number) => {
let result = Complex.fromPtr(ptr);
releasePtr(ptr);
});
const lib = dlopen('lib.so', {
add: { args: [FFIType.double, FFIType.double], returns: FFIType.double },
});
lib.symbols.add.async(2.0, 3.0).then((r: number) => console.log(r));
类型推断
dlopen 使用 TypeScript 泛型推断 symbols 的结构,为所有定义的函数名提供 IDE 自动补全。
import { dlopen, FFIType } from 'arkffi';
const lib = dlopen('lib.so', {
myFunc: { args: [FFIType.double, FFIType.double], returns: FFIType.double },
});
lib.symbols.myFunc(2.0, 3.0); // 自动补全
返回值
返回Library 实例。