跳到正文
cccskills
免费在 GitHub 公开

bun-ffi

This skill should be used when the user asks about "bun:ffi", "foreign function interface", "calling C from Bun", "native libraries", "dlopen", "shared libraries", "calling native code", or integrating C/C++ libraries with Bun.

中文简介正在准备中。当前显示原文说明。

查看安装方法

包含的文件(1)

  • SKILL.md7.1 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Bun FFI

Bun's FFI allows calling native C/C++ libraries from JavaScript.

Quick Start

import { dlopen, suffix, FFIType } from "bun:ffi";

// Load library
const lib = dlopen(`libc.${suffix}`, {
  printf: {
    args: [FFIType.cstring],
    returns: FFIType.int,
  },
});

// Call function
lib.symbols.printf("Hello from C!\n");

Loading Libraries

Platform-Specific Paths

import { dlopen, suffix } from "bun:ffi";

// suffix is: "dylib" (macOS), "so" (Linux), "dll" (Windows)

// System library
const libc = dlopen(`libc.${suffix}`, { ... });

// Custom library
const myLib = dlopen(`./libmylib.${suffix}`, { ... });

// Absolute path
const sqlite = dlopen("/usr/lib/libsqlite3.so", { ... });

Cross-Platform Loading

function getLibPath(name: string): string {
  const platform = process.platform;
  const paths = {
    darwin: `/usr/local/lib/lib${name}.dylib`,
    linux: `/usr/lib/lib${name}.so`,
    win32: `C:\\Windows\\System32\\${name}.dll`,
  };
  return paths[platform] || paths.linux;
}

const lib = dlopen(getLibPath("mylib"), { ... });

FFI Types

import { FFIType } from "bun:ffi";

const types = {
  // Integers
  i8: FFIType.i8,        // int8_t
  i16: FFIType.i16,      // int16_t
  i32: FFIType.i32,      // int32_t / int
  i64: FFIType.i64,      // int64_t / long long

  // Unsigned integers
  u8: FFIType.u8,        // uint8_t
  u16: FFIType.u16,      // uint16_t
  u32: FFIType.u32,      // uint32_t
  u64: FFIType.u64,      // uint64_t

  // Floats
  f32: FFIType.f32,      // float
  f64: FFIType.f64,      // double

  // Pointers
  ptr: FFIType.ptr,      // void*
  cstring: FFIType.cstring, // const char*

  // Other
  bool: FFIType.bool,    // bool
  void: FFIType.void,    // void
};

Function Definitions

import { dlopen, FFIType, ptr, CString } from "bun:ffi";

const lib = dlopen("./libmath.so", {
  // Simple function
  add: {
    args: [FFIType.i32, FFIType.i32],
    returns: FFIType.i32,
  },

  // String function
  greet: {
    args: [FFIType.cstring],
    returns: FFIType.cstring,
  },

  // Pointer function
  allocate: {
    args: [FFIType.u64],
    returns: FFIType.ptr,
  },

  // Void function
  log_message: {
    args: [FFIType.cstring],
    returns: FFIType.void,
  },

  // No args
  get_version: {
    args: [],
    returns: FFIType.cstring,
  },
});

// Call functions
const sum = lib.symbols.add(1, 2); // 3
const message = lib.symbols.greet(ptr(Buffer.from("World\0")));

Working with Strings

import { dlopen, FFIType, ptr, CString } from "bun:ffi";

// Passing strings to C
const str = Buffer.from("Hello\0"); // Must be null-terminated
lib.symbols.print_string(ptr(str));

// Receiving strings from C
const result = lib.symbols.get_string();
const jsString = new CString(result); // Convert to JS string
console.log(jsString.toString());

Working with Pointers

import { dlopen, FFIType, ptr, toArrayBuffer } from "bun:ffi";

const lib = dlopen("./libdata.so", {
  create_buffer: {
    args: [FFIType.u64],
    returns: FFIType.ptr,
  },
  fill_buffer: {
    args: [FFIType.ptr, FFIType.u8, FFIType.u64],
    returns: FFIType.void,
  },
  free_buffer: {
    args: [FFIType.ptr],
    returns: FFIType.void,
  },
});

// Allocate buffer
const size = 1024;
const bufPtr = lib.symbols.create_buffer(size);

// Fill buffer
lib.symbols.fill_buffer(bufPtr, 0xff, size);

// Read buffer as ArrayBuffer
const arrayBuffer = toArrayBuffer(bufPtr, 0, size);
const view = new Uint8Array(arrayBuffer);
console.log(view); // [255, 255, 255, ...]

// Free buffer
lib.symbols.free_buffer(bufPtr);

Structs

import { dlopen, FFIType, ptr } from "bun:ffi";

// C struct:
// struct Point { int32_t x; int32_t y; };

const lib = dlopen("./libgeom.so", {
  create_point: {
    args: [FFIType.i32, FFIType.i32],
    returns: FFIType.ptr, // Returns Point*
  },
  get_distance: {
    args: [FFIType.ptr, FFIType.ptr],
    returns: FFIType.f64,
  },
});

// Create struct manually
const point = new ArrayBuffer(8); // 2 x int32
const view = new DataView(point);
view.setInt32(0, 10, true); // x = 10
view.setInt32(4, 20, true); // y = 20

// Pass to C
lib.symbols.get_distance(ptr(point), ptr(point));

Callbacks

import { dlopen, FFIType, callback } from "bun:ffi";

const lib = dlopen("./libsort.so", {
  sort_array: {
    args: [FFIType.ptr, FFIType.u64, FFIType.ptr], // callback
    returns: FFIType.void,
  },
});

// Create callback
const compareCallback = callback(
  {
    args: [FFIType.ptr, FFIType.ptr],
    returns: FFIType.i32,
  },
  (a, b) => {
    const aVal = new DataView(toArrayBuffer(a, 0, 4)).getInt32(0, true);
    const bVal = new DataView(toArrayBuffer(b, 0, 4)).getInt32(0, true);
    return aVal - bVal;
  }
);

// Use callback
lib.symbols.sort_array(arrayPtr, length, compareCallback.ptr);

// Close callback when done
compareCallback.close();

Example: SQLite

import { dlopen, FFIType, ptr, CString } from "bun:ffi";

const sqlite = dlopen("libsqlite3.dylib", {
  sqlite3_open: {
    args: [FFIType.cstring, FFIType.ptr],
    returns: FFIType.i32,
  },
  sqlite3_exec: {
    args: [FFIType.ptr, FFIType.cstring, FFIType.ptr, FFIType.ptr, FFIType.ptr],
    returns: FFIType.i32,
  },
  sqlite3_close: {
    args: [FFIType.ptr],
    returns: FFIType.i32,
  },
});

// Open database
const dbPtrArray = new BigInt64Array(1);
const dbPath = Buffer.from("test.db\0");
sqlite.symbols.sqlite3_open(ptr(dbPath), ptr(dbPtrArray));
const db = dbPtrArray[0];

// Execute query
const sql = Buffer.from("CREATE TABLE test (id INTEGER);\0");
sqlite.symbols.sqlite3_exec(db, ptr(sql), null, null, null);

// Close
sqlite.symbols.sqlite3_close(db);

Memory Management

// Manual allocation
const buffer = new ArrayBuffer(1024);
const pointer = ptr(buffer);

// Buffer stays valid as long as ArrayBuffer exists
// JavaScript GC will clean up ArrayBuffer

// For C-allocated memory, call C's free function
lib.symbols.free(cPointer);

Thread Safety

// FFI calls are synchronous and block the main thread
// For long-running operations, use Web Workers:

// worker.ts
import { dlopen } from "bun:ffi";
const lib = dlopen(...);

self.onmessage = (e) => {
  const result = lib.symbols.expensive_operation(e.data);
  self.postMessage(result);
};

Common Errors

ErrorCauseFix
Library not foundWrong pathCheck library path
Symbol not foundWrong function nameCheck function export
Type mismatchWrong FFI typesMatch C types exactly
Segmentation faultMemory errorCheck pointer validity

When to Load References

Load references/type-mappings.md when:

  • Complex type conversions
  • Struct layouts
  • Union types

Load references/performance.md when:

  • Optimizing FFI calls
  • Batching operations
  • Memory pooling

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

100+ animated React components (Aceternity UI) for Next.js with Tailwind. Use for hero sections, parallax, 3D effects, or encountering animation, shadcn CLI integration errors.

中文简介正在准备中。当前显示原文说明。

secondsky/claude-skills2312026年10月20日 更新

Secure API authentication with JWT, OAuth 2.0, API keys. Use for authentication systems, third-party integrations, service-to-service communication, or encountering token management, security headers, auth flow errors.

中文简介正在准备中。当前显示原文说明。

secondsky/claude-skills2312026年10月20日 更新

Creates comprehensive API changelogs documenting breaking changes, deprecations, and migration strategies for API consumers. Use when managing API versions, communicating breaking changes, or creating upgrade guides.

中文简介正在准备中。当前显示原文说明。

secondsky/claude-skills2312026年10月20日 更新

Verifies API contracts between services using consumer-driven contracts, schema validation, and tools like Pact. Use when testing microservices communication, preventing breaking changes, or validating OpenAPI specifications.

中文简介正在准备中。当前显示原文说明。

secondsky/claude-skills2312026年10月20日 更新

Master REST and GraphQL API design principles to build intuitive, scalable, and maintainable APIs that delight developers. Use when designing new APIs, reviewing API specifications, or establishing API design standards.

中文简介正在准备中。当前显示原文说明。

secondsky/claude-skills2312026年10月20日 更新

Implements standardized API error responses with proper status codes, logging, and user-friendly messages. Use when building production APIs, implementing error recovery patterns, or integrating error monitoring services.

中文简介正在准备中。当前显示原文说明。

secondsky/claude-skills2312026年10月20日 更新

查看 secondsky 的全部技能

报告此技能的问题