> ## Documentation Index
> Fetch the complete documentation index at: https://docs.arkffi.hmbill.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# dlopen

> 加载共享库并获取类型化函数定义

`dlopen` 加载共享库并返回带类型化符号的 [`Library`](/zh/api/library) 实例。

## 语法

```typescript theme={null}
function dlopen<Fns extends Record<string, FFIFunction>>(
  libName: string,
  defs: Fns,
): Library<Fns>;
```

## 示例

```typescript theme={null}
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

```typescript theme={null}
interface FFIFunction {
  args: (string | StructSchema)[];  // 参数类型编码，支持 StructSchema
  returns: string | StructSchema;   // 返回类型编码，支持 StructSchema
  threadsafe?: boolean;             // 用于 JSCallback 定义
}
```

## 结构体类型支持

`args` 和 `returns` 除了接受 `FFIType.*` 字符串，还可传入 `StructSchema` 实例，用于在寄存器中传递的小型 HFA 结构体。

```typescript theme={null}
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` 方法，用于在工作线程上非阻塞调用：

```typescript theme={null}
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);
});
```

对于基本返回类型，Promise 直接 resolve 值：

```typescript theme={null}
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 自动补全。

```typescript theme={null}
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`](/zh/api/library) 实例。
