Pointer
Pointer 类提供对原始内存的读写操作,支持所有基本 C 类型的读写以及 C 字符串和指针操作。
导入
ts
import { Pointer } from 'senri_ffi';创建 Pointer
Pointer 通常不直接使用 new 创建,而是通过以下方式获得:
alloc(size) — 分配新内存
ts
import { alloc } from 'senri_ffi';
const ptr = alloc(64); // 分配 64 字节addressOf(buffer) — 从 ArrayBuffer 获取指针
ts
import { addressOf } from 'senri_ffi';
const buf = new ArrayBuffer(16);
const ptr = addressOf(buf);callback() — 创建回调返回指针
ts
import { callback, types } from 'senri_ffi';
const cb = callback(types.int32, [types.int32, types.int32], (a, b) => a + b);
// cb 是一个 Pointer 实例new Pointer(underlying) — 手动构造
ts
const ptr = new Pointer({ __ptr: 0x123456, __size: 64 });读方法
所有读方法接受一个可选的 offset 参数(默认为 0)。
ts
ptr.readInt8(offset?: number): number
ptr.readUint8(offset?: number): number
ptr.readInt16(offset?: number): number
ptr.readUint16(offset?: number): number
ptr.readInt32(offset?: number): number
ptr.readUint32(offset?: number): number
ptr.readInt64(offset?: number): bigint
ptr.readUint64(offset?: number): bigint
ptr.readFloat32(offset?: number): number
ptr.readFloat64(offset?: number): number注意: 64 位整数读写返回/接受 bigint 类型。
ts
const value = ptr.readInt32(0); // 从偏移 0 读取 int32
const bigVal = ptr.readInt64(8); // 从偏移 8 读取 int64 (BigInt)readPointer(offset?) — 读取指针
ts
ptr.readPointer(offset?: number): Pointer从指定偏移读取一个 64 位地址值,返回新的 Pointer 实例。
ts
const nextPtr = ptr.readPointer(0);readCString(offset?) — 读取 C 字符串
ts
ptr.readCString(offset?: number): string从指定偏移开始读取,直到遇到 null 字节(\0),返回解码后的字符串。
ts
const str = ptr.readCString(4); // 从偏移 4 开始读取注意: 需要指针有后备缓冲区(__buf),否则返回空字符串。
写方法
所有写方法接受 offset 和 value 参数。
ts
ptr.writeInt8(offset: number, v: number): void
ptr.writeUint8(offset: number, v: number): void
ptr.writeInt16(offset: number, v: number): void
ptr.writeUint16(offset: number, v: number): void
ptr.writeInt32(offset: number, v: number): void
ptr.writeUint32(offset: number, v: number): void
ptr.writeInt64(offset: number, v: bigint): void
ptr.writeUint64(offset: number, v: bigint): void
ptr.writeFloat32(offset: number, v: number): void
ptr.writeFloat64(offset: number, v: number): voidts
ptr.writeInt32(0, 42);
ptr.writeFloat64(4, 3.14);writePointer(offset, ptr) — 写入指针
ts
ptr.writePointer(offset: number, ptr: Pointer | number): void将指针地址写入指定偏移。
ts
const target = alloc(16);
ptr.writePointer(0, target); // 写入 target 的地址writeCString(offset, str) — 写入 C 字符串
ts
ptr.writeCString(offset: number, str: string): void将字符串以 UTF-8 编码写入,自动追加 null 结尾符。
ts
ptr.writeCString(0, 'hello'); // 写入 "hello\0"其他方法
add(offset) — 指针偏移
ts
ptr.add(offset: number): Pointer返回一个新的 Pointer,地址偏移 offset 字节。
ts
const head = alloc(64);
const tail = head.add(32); // tail 指向 head 的中间位置toBigInt() — 转为 BigInt
ts
ptr.toBigInt(): bigint返回指针地址的 BigInt 表示。
address — 获取地址
ts
ptr.address: number只读 getter,返回指针的地址值。
完整示例
ts
import { alloc, Pointer } from 'senri_ffi';
// 分配 64 字节
const ptr = alloc(64);
// 写入数据
ptr.writeInt32(0, 42); // 偏移 0: int32 = 42
ptr.writeFloat64(4, 3.14159); // 偏移 4: float64 = 3.14159
ptr.writeCString(12, 'hello'); // 偏移 12: "hello\0"
// 读取数据
console.log(ptr.readInt32(0)); // 42
console.log(ptr.readFloat64(4)); // 3.14159
console.log(ptr.readCString(12)); // "hello"
// 指针操作
console.log(ptr.address); // 原始地址值
const offsetPtr = ptr.add(12);
console.log(offsetPtr.readCString(0)); // "hello"
// 指针链
ptr.writePointer(0, offsetPtr);
const recovered = ptr.readPointer(0);
console.log(recovered.readCString(0)); // "hello"内部结构
Pointer 内部使用 _data 对象存储底层引用:
ts
{
__ptr: number, // 指针地址
__buf: ArrayBuffer, // 后备缓冲区(可选)
__size: number, // 缓冲区大小
__u8: Uint8Array, // Bun 适配器的 Uint8Array 视图(可选)
}读写操作通过 DataView 访问后备缓冲区。如果指针没有后备缓冲区,读写会抛出 FFIError(但 C 字符串读取会安全返回空字符串)。
