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

# CFunction

> 将原始 C 函数指针包装为可调用的 ArkTS 函数

`CFunction` 将原始 C 函数指针包装为可调用的 ArkTS 函数。

## 示例

```typescript theme={null}
import ffi from 'liblibrary.so';
import { CFunction, FFIType } from 'arkffi';

const handle = ffi.load('libffi_target.so');
const ptr = ffi.getSymbolPtr(handle, 'add');

const add = CFunction({
  args: [FFIType.double, FFIType.double],
  returns: FFIType.double,
  ptr: ptr,
});

add(2.0, 3.0); // → 5.0
add.close();
ffi.close(handle);
```

## 语法

```typescript theme={null}
function CFunction(def: {
  args: string[];
  returns: string;
  ptr: number;
}): {
  (...args: any[]): number;
  close(): void;
};
```

## 参数

| 参数            | 类型         | 说明                                                             |
| ------------- | ---------- | -------------------------------------------------------------- |
| `def.args`    | `string[]` | C 函数参数类型编码，支持 `FFIType.callback`（调用时自动从 JSCallback 中提取 `.ptr`） |
| `def.returns` | `string`   | C 函数返回类型编码                                                     |
| `def.ptr`     | `number`   | 原始函数指针地址                                                       |

## 回调类型参数

当参数类型为 `FFIType.callback`（`'k'`）时，传入的 JSCallback 会被自动提取其 `.ptr`：

```typescript theme={null}
let fn = CFunction({
  args: [FFIType.callback, FFIType.int32],
  returns: FFIType.int32,
  ptr: applyPtr,
});
fn(cb, 21); // cb.ptr 自动作为第一个参数传入
```

## 获取指针

使用 `ffi.getSymbolPtr(handle, name)`：

```typescript theme={null}
import { CFunction, FFIType } from 'arkffi';
import ffi from 'liblibrary.so';

const handle = ffi.load('lib.so');
const ptr = ffi.getSymbolPtr(handle, 'calculate');
const fn = CFunction({ args: [FFIType.int32, FFIType.double], returns: FFIType.double, ptr });
fn(42, 3.14);
fn.close();
ffi.close(handle);
```

## 异步版本：`AsyncCFunction`

`AsyncCFunction` 签名与 `CFunction` 一致，但返回 `Promise<number>`，在后台线程执行不阻塞主线程。

```typescript theme={null}
import { AsyncCFunction, FFIType } from 'arkffi';
import ffi from 'liblibrary.so';

const handle = ffi.load('lib.so');
const ptr = ffi.getSymbolPtr(handle, 'calculate');
const fn = AsyncCFunction({ args: [FFIType.int32, FFIType.double], returns: FFIType.double, ptr });

fn(42, 3.14).then((r: number) => {
  console.log(r);
  fn.close();
  ffi.close(handle);
});
```

| 对比    | `CFunction`  | `AsyncCFunction`      |
| ----- | ------------ | --------------------- |
| 返回值   | `number`（同步） | `Promise<number>`（异步） |
| 阻塞主线程 | ✅ 是          | ❌ 否                   |
