> ## 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.

# JSCallback

> 将 ArkTS 函数包装为 C 回调

`JSCallback` 包装 ArkTS 函数，使其可用于期望函数指针的 C 代码。

## 示例

```typescript theme={null}
import { JSCallback, FFIType } from 'arkffi';

const cb = new JSCallback(
  (a: number, b: number): number => a + b,
  { args: [FFIType.int32, FFIType.int32], returns: FFIType.int32 },
);

cb.call(2, 3); // → 5
cb.ptr;        // → 槽位句柄
cb.close();
```

## 构造函数

```typescript theme={null}
constructor(
  callback: (...args: any[]) => any,
  def: {
    args: string[];
    returns: string;
    threadsafe?: boolean;
  },
);
```

| 参数               | 类型         | 默认值     | 说明            |
| ---------------- | ---------- | ------- | ------------- |
| `callback`       | `Function` | —       | 要包装的 ArkTS 函数 |
| `def.args`       | `string[]` | —       | C 函数参数类型编码    |
| `def.returns`    | `string`   | —       | C 函数返回类型编码    |
| `def.threadsafe` | `boolean`  | `false` | 是否可从任意线程调用    |

## 属性

### `ptr`

```typescript theme={null}
get ptr(): number;
```

返回可用于原生 C 代码的函数指针地址。

* **非线程安全**：返回槽位句柄（小整数）。
* **线程安全**：返回真实的可执行蹦床函数地址，可传给 C 函数作为回调参数。

### `getHandle()`

```typescript theme={null}
getHandle(): number;
```

返回内部槽位句柄，可用于 `ffi.invokeCallback()` 和 `ffi.callCallbackThreadSafe()`。

### `threadsafe`

```typescript theme={null}
readonly threadsafe: boolean;
```

回调是否以线程安全模式创建。

## 方法

### `call()`

```typescript theme={null}
call(...args: any[]): any;
```

调用 ArkTS 回调。

```typescript theme={null}
cb.call(7);  // → 70
```

### `close()`

```typescript theme={null}
close(): void;
```

释放回调资源。

```typescript theme={null}
cb.close();
cb.call(1); // 抛出异常
```

## 线程安全回调

```typescript theme={null}
const cb = new JSCallback(fn, {
  args: [FFIType.int32],
  returns: FFIType.double,
  threadsafe: true,
});
cb.threadsafe; // → true
```

## 闭包捕获

```typescript theme={null}
let factor = 10;
const cb = new JSCallback(
  (x: number): number => x * factor,
  { args: [FFIType.int32], returns: FFIType.int32 },
);
cb.call(5); // → 50
factor = 20;
cb.call(5); // → 100
cb.close();
```
