为了将 JS 函数传递给需要回调的 C 函数,您必须首先创建一个具有预期返回类型和参数的回调类型。该语法类似于用于从共享库加载函数的语法。
// ES6 syntax: import koffi from 'koffi';
const koffi = require('koffi');
// With the classic syntax, this callback expects an integer and returns nothing
const ExampleCallback = koffi.proto('ExampleCallback', 'void', ['int']);
// With the prototype parser, this callback expects a double and float, and returns the sum as a double
const AddDoubleFloat = koffi.proto('double AddDoubleFloat(double d, float f)');
对于替代调用约定(例如stdcall在 Windows x86 32 位上),您可以使用经典语法指定为第一个参数,或者在原型字符串中的返回类型之后指定,如下所示:
const HANDLE = koffi.pointer('HANDLE', koffi.opaque());
const HWND = koffi.alias('HWND', HANDLE);
// These two declarations work the same, and use the __stdcall convention on Windows x86
const EnumWindowsProc = koffi.proto('bool __stdcall EnumWindowsProc (HWND hwnd, long lParam)');
const EnumWindowsProc = koffi.proto('__stdcall', 'EnumWindowsProc', 'bool', ['HWND', 'long']);
您必须确保调用约定正确(例如为 Windows API 回调指定 __stdcall),否则您的代码将在 Windows 32 位上崩溃。
class ValueStore {
constructor(value) { this.value = value; }
get() { return this.value; }
}
let store = new ValueStore(42);
let cb1 = koffi.register(store.get, 'IntCallback *'); // If a C function calls cb1 it will fail because this will be undefined
let cb2 = koffi.register(store, store.get, 'IntCallback *'); // However in this case, this will match the store object