Skip to content

bun:ffi 는 JavaScript 에서 C 를 낮은 오버헤드로 컴파일하고 실행하기 위한 실험적 지원을 제공합니다.


사용법 (bun:ffi 의 cc)

자세한 내용은 소개 블로그 포스트 를 참조하세요.

JavaScript:

ts
import { cc } from "bun:ffi";
import source from "./hello.c" with { type: "file" };

const {
  symbols: { hello },
} = cc({
  source,
  symbols: {
    hello: {
      args: [],
      returns: "int",
    },
  },
});

console.log("What is the answer to the universe?", hello());

C 소스:

c
int hello() {
  return 42;
}

hello.js 를 실행하면 다음이 출력됩니다.

sh
bun hello.js
What is the answer to the universe? 42

내부적으로 ccTinyCC 를 사용하여 C 코드를 컴파일하고 JavaScript 런타임과 링크하며, 타입을 제자리에서 효율적으로 변환합니다.

원시 타입

dlopen 과 동일한 FFIType 값이 cc 에서 지원됩니다.

FFITypeC 타입별칭
cstringchar*
function(void*)(*)()fn, callback
ptrvoid*pointer, void*, char*
i8int8_tint8_t
i16int16_tint16_t
i32int32_tint32_t, int
i64int64_tint64_t
i64_fastint64_t
u8uint8_tuint8_t
u16uint16_tuint16_t
u32uint32_tuint32_t
u64uint64_tuint64_t
u64_fastuint64_t
f32floatfloat
f64doubledouble
boolbool
charchar
napi_envnapi_env
napi_valuenapi_value

문자열, 객체 및 비원시 타입

C 타입과 1:1 로 매핑되지 않는 문자열, 객체 및 기타 비원시 타입을 더 쉽게 작업할 수 있도록 cc 는 N-API 를 지원합니다.

C 함수에서 타입 변환 없이 JavaScript 값을 전달하거나 받으려면 napi_value 를 사용할 수 있습니다.

또한 JavaScript 함수를 호출하는 데 사용되는 N-API 환경을 받기 위해 napi_env 를 전달할 수도 있습니다.

C 문자열을 JavaScript 로 반환

예를 들어 C 에 문자열이 있는 경우 다음과 같이 JavaScript 로 반환할 수 있습니다.

ts
import { cc } from "bun:ffi";
import source from "./hello.c" with { type: "file" };

const {
  symbols: { hello },
} = cc({
  source,
  symbols: {
    hello: {
      args: ["napi_env"],
      returns: "napi_value",
    },
  },
});

const result = hello();

C 에서:

c
#include <node/node_api.h>

napi_value hello(napi_env env) {
  napi_value result;
  napi_create_string_utf8(env, "Hello, Napi!", NAPI_AUTO_LENGTH, &result);
  return result;
}

이를 사용하여 객체나 배열과 같은 다른 타입도 반환할 수 있습니다.

c
#include <node/node_api.h>

napi_value hello(napi_env env) {
  napi_value result;
  napi_create_object(env, &result);
  return result;
}

cc 참조

library: string[]

library 배열은 C 코드와 링크되어야 하는 라이브러리를 지정하는 데 사용됩니다.

ts
type Library = string[];

cc({
  source: "hello.c",
  library: ["sqlite3"],
});

symbols

symbols 객체는 JavaScript 에 노출되어야 하는 함수와 변수를 지정하는 데 사용됩니다.

ts
type Symbols = {
  [key: string]: {
    args: FFIType[];
    returns: FFIType;
  };
};

source

source 는 JavaScript 런타임과 컴파일되고 링크되어야 하는 C 코드에 대한 파일 경로입니다.

ts
type Source = string | URL | BunFile;

cc({
  source: "hello.c",
  symbols: {
    hello: {
      args: [],
      returns: "int",
    },
  },
});

flags: string | string[]

flags 는 TinyCC 컴파일러에 전달되어야 하는 선택적 문자열 배열입니다.

ts
type Flags = string | string[];

이것은 포함 디렉토리에 대한 -I 와 전처리기 정의에 대한 -D 와 같은 플래그입니다.

define: Record<string, string>

define 은 TinyCC 컴파일러에 전달되어야 하는 선택적 객체입니다.

ts
type Defines = Record<string, string>;

cc({
  source: "hello.c",
  define: {
    NDEBUG: "1",
  },
});

이것은 TinyCC 컴파일러에 전달되는 전처리기 정의입니다.

Bun by www.bunjs.com.cn 편집