节点 ffi napi,调用返回 true 但指针中没有结果
Posted
技术标签:
【中文标题】节点 ffi napi,调用返回 true 但指针中没有结果【英文标题】:Node ffi napi, call return true but no result in pointer 【发布时间】:2021-10-25 22:27:09 【问题描述】:需要在电子中使用一些 ffi napi,我试图让它工作,从小开始。试图理解并获得 ffi 有效,但无法获得结果。我知道我将指针传递给结构,结果将写入其中。但是调用 return True 并且在指定的指针中没有结果。没有新数据。请帮忙。
const ffi = require("ffi-napi");
const ref = require("ref-napi");
const Struct = require("ref-struct-di")(ref);
const ABM_NEW = 0;
const ABM_QUERYPOS = 0x2;
const ABM_GETTASKBARPOS = 5; // 0x00000005
const ABM_GETSTATE = 0x4;
const ABEdgeLeft = 0;
const RECT_Struct = Struct(
left: "long",
top: "long",
right: "long",
bottom: "long",
);
const APPBARDATA_Struct = Struct(
cbSize: "uint32",
hWnd: "int",
uCallbackMessage: "uint32",
uEdge: "uint32",
rc: RECT_Struct,
lParam: "int64",
);
export const shell32 = ffi.Library("shell32.dll",
SHAppBarMessage: ["long", ["int", APPBARDATA_Struct]],
);
export const user32 = ffi.Library("user32.dll",
GetWindowRect: ["bool", ["long", RECT_Struct]],
);
const data = new APPBARDATA_Struct();
data.cbSize = APPBARDATA_Struct.size;
const result = shell32.SHAppBarMessage(ABM_GETTASKBARPOS, data);
const rect = new RECT_Struct();
const result2 = user32.GetWindowRect(0x20674, rect);
console.log(`result: $JSON.stringify(result): $JSON.stringify(data)`);
console.log(`result2: $JSON.stringify(result2): $JSON.stringify(rect)`);
结果
result: 1: "cbSize":40,"hWnd":0,"uCallbackMessage":0,"uEdge":0,"rc":"left":0,"top":0,"right":0,"bottom":0,"lParam":0
result2: true: "left":0,"top":0,"right":0,"bottom":0
当我测试时,函数调用有效 - 它返回 1 (true) 和 hwnd 存在的窗口,如果关闭则返回 0。但我无法从缓冲区中获取结果数据,这让我很生气。
【问题讨论】:
【参考方案1】:首先,我不太了解指针。但是,我对同样的问题感兴趣,所以我尝试并找到了解决方案。等我知道具体原理后再修改。
您使用的 GetWindowRect 和 SHAppBarMessage 函数从 C++ 接收结构指针类型参数。这些函数具有通过返回值通知成功与否以及在接收到的struct上记录数据的功能。因此,在 C++ 中测试函数时,在构建结构类型参数而不添加与符号(例如 &rect 或 &data)符号时会发生错误。
ref-struct-di 的示例显示了使用指向参数的结构指针的示例。我认为这是将结构指针传递给函数,并且在如下修改代码时它可以工作。使用struct作为参数的部分和用ffi定义函数的部分必须修改。请参考代码中的cmets!
// GetWindowRect Example
const RECT = Struct(
left: ref.types.long,
top: ref.types.long,
right: ref.types.long,
bottom: ref.types.long,
);
const user32 = ffi.Library('user32.dll',
GetWindowRect: ['bool', ['long', ref.refType(RECT)]], // RECT_Struct -> ref.refType(RECT_Struct) or 'pointer'
);
const rect = new RECT;
console.log(user32.GetWindowRect(0x007B0F10, rect.ref())); // 0x007B0F10 is one of my windows that I found with Spy++.
console.log('left', rect.left);
console.log('right', rect.right);
console.log('top', rect.top);
console.log('bottom', rect.bottom);
// SHAppBarMessage Example
const ABM_GETTASKBARPOS = 5;
const APPBARDATA = Struct(
cbSize: ref.types.uint32,
hWnd: ref.types.long,
uCallbackMessage: ref.types.uint32,
uEdge: ref.types.uint32,
rc: RECT,
lParam: ref.types.int64,
);
const shell32 = ffi.Library('shell32.dll',
SHAppBarMessage: ['long', ['int', ref.refType(APPBARDATA)]], // APPBARDATA_Struct -> ref.refType(APPBARDATA_Struct) or 'pointer'
);
const data = new APPBARDATA();
data.cbSize = APPBARDATA.size;
console.log(shell32.SHAppBarMessage(ABM_GETTASKBARPOS, data.ref()));
console.log('cbSize', data.cbSize);
console.log('hWnd', data.hWnd);
console.log('uCallbackMessage', data.uCallbackMessage);
console.log('uEdge', data.uEdge);
console.log('rc.left', data.rc.left);
console.log('rc.right', data.rc.right);
console.log('rc.top', data.rc.top);
console.log('rc.bottom', data.rc.bottom);
console.log('lParam', data.lParam);
【讨论】:
是的,问题出在这,“指针”而不是 ref.refType(*) 也可以。谢谢! 老兄,你这个天才,这解决了我几分钟前发布的问题! (***.com/questions/69695067/…) 我更改为[INT, WPARAM, ref.refType(KBDLLHOOKSTRUCT)],
和`$JSON.stringify(lParam.deref())` 并且它有效!谢谢,你让我见识了!!!这个问题让我抓狂,它在 x64 上完美运行,我知道为什么。现在我明白了!以上是关于节点 ffi napi,调用返回 true 但指针中没有结果的主要内容,如果未能解决你的问题,请参考以下文章