输出参数

输出和输入/输出

为了简单起见,并且由于 Javascript 仅具有原始类型的值语义,Koffi 可以编组出(或输入/输出)多种类型的参数:

要将参数从仅输入更改为输出或输入/输出,请使用以下函数:

  • koffi.out()在指针上,例如koffi.out(koffi.pointer(timeval))(其中 timeval 是结构类型)

  • koffi.inout()用于双输入/输出参数

当使用类似 C 的原型字符串和类似 MSDN 的类型限定符声明函数时,也可以执行相同的操作:

  • _Out_对于输出参数

  • _Inout_用于双输入/输出参数

原始值

此 Windows 示例枚举所有 Chrome 窗口及其 PID 和标题。该GetWindowThreadProcessId()函数说明了如何从输出参数获取原始值。

// ES6 syntax: import koffi from 'koffi';
const koffi = require('koffi');

const user32 = koffi.load('user32.dll');

const DWORD = koffi.alias('DWORD', 'uint32_t');
const HANDLE = koffi.pointer(koffi.opaque('HANDLE'));
const HWND = koffi.alias('HWND', HANDLE);

const FindWindowEx = user32.func('HWND __stdcall FindWindowExW(HWND hWndParent, HWND hWndChildAfter, const char16_t *lpszClass, const char16_t *lpszWindow)');
const GetWindowThreadProcessId = user32.func('DWORD __stdcall GetWindowThreadProcessId(HWND hWnd, _Out_ DWORD *lpdwProcessId)');
const GetWindowText = user32.func('int __stdcall GetWindowTextA(HWND hWnd, _Out_ uint8_t *lpString, int nMaxCount)');

for (let hwnd = null;;) {
    hwnd = FindWindowEx(0, hwnd, 'Chrome_WidgetWin_1', null);

    if (!hwnd)
        break;

    // Get PID
    let pid;
    {
        let ptr = [null];
        let tid = GetWindowThreadProcessId(hwnd, ptr);

        if (!tid) {
            // Maybe the process ended in-between?
            continue;
        }

        pid = ptr[0];
    }

    // Get window title
    let title;
    {
        let buf = Buffer.allocUnsafe(1024);
        let length = GetWindowText(hwnd, buf, buf.length);

        if (!length) {
            // Maybe the process ended in-between?
            continue;
        }

        title = koffi.decode(buf, 'char', length);
    }

    console.log({ PID: pid, Title: title });
}

结构示例

此示例调用 POSIX 函数gettimeofday(),并使用类似原型的语法。

不透明类型示例

此示例打开一个内存 SQLite 数据库,并使用节点 ffi 样式的函数声明语法。

字符串缓冲区示例

Koffi 2.2 中的新功能

此示例调用 C 函数将两个字符串连接到预分配的字符串缓冲区。由于 JS 字符串是不可变的,因此您必须传递带有单个字符串的数组。

Last updated