Skip to content

يدعم bun:ffi تجريبيًا تجميع وتشغيل C من JavaScript مع حمل زائد منخفض.


الاستخدام (cc في bun:ffi)

راجع منشور المقدمة لمزيد من المعلومات.

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

تحت الغطاء، يستخدم cc TinyCC لتجميع كود C ثم ربطه بوقت تشغيل JavaScript، مما يحول الأنواع بكفاءة في المكان.

الأنواع البدائية

نفس قيم FFIType في dlopen مدعومة في cc.

FFITypeC TypeAliases
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

السلاسل والكائنات والأنواع غير البدائية

لتسهيل العمل مع السلاسل والكائنات والأنواع غير البدائية الأخرى التي لا تتطابق 1:1 مع أنواع C، يدعم cc N-API.

لتمرير أو استقبال قيم JavaScript بدون أي تحويلات أنواع من دالة C، يمكنك استخدام napi_value.

يمكنك أيضًا تمرير napi_env لاستقبال بيئة N-API المستخدمة لاستدعاء دالة JavaScript.

إرجاع سلسلة 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 هو مسار ملف إلى كود C الذي يجب تجميعه وربطه بوقت تشغيل JavaScript.

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 بواسطة www.bunjs.com.cn تحرير