导出的变量

预计阅读时间: 4 分钟

源文档 - Exported variables

变量定义

新增于 Koffi 2.6

要查找导出的变量并声明一个变量,请使用 lib.symbol(name, type)。你需要指定它的名称和类型。

int my_int = 42;
const char *my_string = NULL;
const my_int = lib.symbol("my_int", "int");
const my_string = lib.symbol("my_string", "const char *");

你不能直接操作这些变量,需要使用:

解码为 JS 值

新增于 Koffi 2.2,Koffi 2.3 有变更

使用 koffi.decode() 解码 C 指针,这些指针可以包装为外部对象或简单的数字。

一些参数是可选的,此函数可以以几种方式调用:

  • koffi.decode(value, type):无偏移量
  • koffi.decode(value, offset, type):在解码前显式添加到指针的偏移量

默认情况下,Koffi 在解码字符串时会期望以 NUL 结尾。如果你需要指定字符串长度,请参见下文。

以下示例展示了如何解码一个整数和一个 C 字符串变量。

int my_int = 42;
const char *my_string = "foobar";
const my_int = lib.symbol("my_int", "int");
const my_string = lib.symbol("my_string", "const char *");

console.log(koffi.decode(my_int, "int")); // 输出 42
console.log(koffi.decode(my_string, "const char *")); // 输出 "foobar"

还有一个可选的结尾 length 参数,你可以在两种情况下使用它:

  • 用于指定非 NUL 结尾字符串中要解码的字节数:koffi.decode(value, 'char *', 5)
  • 将连续的值解码为数组。例如,以下是如何解码包含 3 个浮点值的数组:koffi.decode(value, 'float', 3)。这相当于 koffi.decode(value, koffi.array('float', 3))

以下示例将解码上面定义的符号 my_string,但只解码前三个字节。

// 只从 C 字符串 my_string 解码 3 个字节
console.log(koffi.decode(my_string, "const char *", 3)); // 输出 "foo"
记录

在 Koffi 2.2 及更早版本中,长度参数仅用于解码字符串,其他情况下会被忽略。

编码到 C 内存

新增于 Koffi 2.6

使用 koffi.encode() 将 JS 值编码为 C 符号或指针,这些指针可以包装为外部对象或简单的数字。

一些参数是可选的,此函数可以以几种方式调用:

  • koffi.encode(ref, type, value):无偏移量
  • koffi.encode(ref, offset, type, value):在编码前显式添加到指针的偏移量

我们将重用上面的示例,并使用 koffi.encode() 更改变量的值。

int my_int = 42;
const char *my_string = NULL;
const my_int = lib.symbol("my_int", "int");
const my_string = lib.symbol("my_string", "const char *");

console.log(koffi.decode(my_int, "int")); // 输出 42
console.log(koffi.decode(my_string, "const char *")); // 输出 null

koffi.encode(my_int, "int", -1);
koffi.encode(my_string, "const char *", "Hello World!");

console.log(koffi.decode(my_int, "int")); // 输出 -1
console.log(koffi.decode(my_string, "const char *")); // 输出 "Hello World!"

在编码字符串(无论是直接编码还是嵌入在数组或结构体中)时,内存将绑定到原始指针值并由 Koffi 管理。你可以反复将相同的字符串赋值,而不会出现内存泄漏或使用后释放的风险。

还有一个可选的结尾 length 参数,你可以用它来编码一个数组。例如,以下是如何编码一个包含 3 个浮点值的数组:koffi.encode(symbol, 'float', [1, 2, 3], 3)。这相当于 koffi.encode(symbol, koffi.array('float', 3), [1, 2, 3])

记录

在 Koffi 2.6.11 之前,长度参数没有正确工作。