> ## 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>`（異步） |
| 阻塞主線程 | ✅ 是          | ❌ 否                   |
