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

# Struct

> 在 ArkTS 中定義和操作 C 結構體

`Struct` 定義 C 結構體的內存佈局，支持序列化/反序列化，可與 `ffi.ptr` 配合傳遞給 C 函數。

## 示例

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

const Point = Struct({
  x: FFIType.int32,
  y: FFIType.int32,
});

const buf = Point.create({ x: 10, y: 20 });
const ptr = ffi.ptr(buf);

const read = Point.fromPtr(somePtr);
console.log(read.x, read.y);
```

## Struct()

```typescript theme={null}
function Struct(fields: Record<string, string | StructSchema>): StructSchema;
```

| 參數       | 類型                                       | 說明               |
| -------- | ---------------------------------------- | ---------------- |
| `fields` | `Record<string, string \| StructSchema>` | 字段名到類型編碼的映射，支持嵌套 |

## StructSchema

### `size`

```typescript theme={null}
readonly size: number;
```

結構體總大小（字節），包含對齊填充。

### `create()`

```typescript theme={null}
create(obj: Record<string, number | bigint | ArrayBuffer>): ArrayBuffer;
```

將對象序列化爲 `ArrayBuffer`。嵌套結構體字段傳入其 `create()` 返回的 `ArrayBuffer`。

### `fromPtr()`

```typescript theme={null}
fromPtr(ptr: number, byteOffset?: number): Record<string, number>;
```

從原始指針讀取結構體數據。**基本類型字段返回數值，嵌套結構體字段返回指針**（該子結構體在內存中的起始地址），需通過子結構體的 `fromPtr` 進一步讀取。

### `get()` / `set()`

```typescript theme={null}
get(buf: ArrayBuffer, field: string): number;
set(buf: ArrayBuffer, field: string, value: number): void;
```

僅支持基本類型字段，嵌套結構體字段返回 `0` / 不操作。

## 嵌套結構體

字段值可以是另一個 `StructSchema`，遞歸計算佈局。

```typescript theme={null}
// C: struct Inner { double x, y; };
// C: struct Outer { struct Inner pos; const char* name; };
const Inner = Struct({
  x: FFIType.double,
  y: FFIType.double,
});
const Outer = Struct({
  pos: Inner,
  name: FFIType.ptr,
});

let buf = Outer.create({
  pos: Inner.create({ x: 1.0, y: 2.0 }),
  name: 0x1234,
});

let r = Outer.fromPtr(ptr);
let innerR = Inner.fromPtr(r.pos);
console.log(innerR.x, innerR.y); // 1.0, 2.0
```

## 與 `dlopen` 配合（HFA 結構體傳參）

對於在寄存器中傳遞的小型 HFA 結構體，可直接將 `StructSchema` 用作 `dlopen` 的 `args` / `returns`：

```typescript theme={null}
// C: complex_t complex_add(complex_t a, complex_t b);
const Complex = Struct({ real: FFIType.double, imag: FFIType.double });
const lib = dlopen(LIB_NAME, {
  complex_add: { args: [Complex, Complex], returns: Complex },
});

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); // { real: 4, imag: 6 }
```

結構體作爲參數時自動展開爲字段值傳入寄存器；作爲返回值時自動分配 buffer，返回 buffer 的指針。通過 `fromPtr` 同步讀取。

## ARM64 對齊規則

| 類型編碼      | C 類型                   | 大小 | 對齊 |
| --------- | ---------------------- | -- | -- |
| `c`       | `char` / `int8_t`      | 1  | 1  |
| `i`       | `int32_t` / `int`      | 4  | 4  |
| `l`       | `int64_t` / `uint64_t` | 8  | 8  |
| `d`       | `double`               | 8  | 8  |
| `f`       | `float`                | 4  | 4  |
| `b`       | `bool`                 | 1  | 1  |
| `s`       | `const char*`（指針）      | 8  | 8  |
| `p` / `k` | `void*` / 函數指針         | 8  | 8  |

嵌套結構體的對齊取其所有子字段對齊的最大值。

```typescript theme={null}
const Mixed = Struct({
  a: FFIType.int8_t,     // offset 0, size 1
  b: FFIType.int32,       // offset 4 (3 byte padding), size 4
  c: FFIType.int8_t,      // offset 8, size 1
});                        // total 12 bytes (3 byte final padding)

const buf = Mixed.create({ a: 1, b: 2, c: 3 });
```

## 與 C 函數配合

```typescript theme={null}
// C: void setPoint(struct Point* p, int x, int y)

const Point = Struct({ x: 'i', y: 'i' });
const lib = dlopen('lib.so', {
  setPoint: { args: [FFIType.ptr, FFIType.int32, FFIType.int32], returns: 'i' },
});

const buf = Point.create({ x: 0, y: 0 });
lib.symbols.setPoint(ffi.ptr(buf), 42, 99);

const result = Point.fromPtr(ffi.ptr(buf));
console.log(result.x, result.y);
```
