bun ffi

安装量: 50
排名: #14843

安装

npx skills add https://github.com/secondsky/claude-skills --skill 'Bun FFI'

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 Error Cause Fix Library not found Wrong path Check library path Symbol not found Wrong function name Check function export Type mismatch Wrong FFI types Match C types exactly Segmentation fault Memory error Check 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

返回排行榜