我能够使用一些基本的Win32 C/C++代码加载某个DLL并调用该DLL中的某个函数。
我调用的函数需要调用者分配的缓冲区的地址,调用者将在给定的偏移量处用16位整数填充该地址。
使用一个调试器和一个断点,我可以看到调用后的内存,在给定的偏移量,16位整数是可以的:低位优先,所以LSB优先。
现在,我想从nodejs
呼叫
const ffi = require('ffi-napi');
const ref = require('ref-napi');
const StructType = require('ref-struct-napi');
const ArrayType = require('ref-array-napi');
const hllapi = ffi.Library('WHLAPI32', {
'WinHLLAPI': [ref.types.void, [ref.refType(ref.types.uint16),
ref.refType(ref.types.void),
ref.refType(ref.types.uint16),
ref.refType(ref.types.uint16)]]
});
var QuerySessionStatusStruct = StructType({
ShortName: ref.types.uchar, // 1
LongName: ArrayType('uchar', 8), // 9
Type: ref.types.uchar, // 10
Characteristics: ref.types.uchar, // 11
Rows: ref.types.uint16, // 13
Cols: ref.types.uint16, // 15
CodePage: ref.types.uint16, // 17
Reserved: ref.types.uchar // 18
});
const function_number = ref.alloc(ref.types.uint16, 22);
const QuerySessionStatusStructInstance = new QuerySessionStatusStruct;
QuerySessionStatusStructInstance.ShortName='B';
const length = ref.alloc(ref.types.uint16, 18);
const ps_position = ref.alloc(ref.types.uint16, 0);
hllapi.WinHLLAPI(function_number, QuerySessionStatusStructInstance.ref(), length, ps_position );
console.log( "RC is: " + ps_position.deref());
console.log( 'Long Name is: '+String.fromCharCode.apply(null, QuerySessionStatusStructInstance.LongName));
console.log( 'Rows is: '+QuerySessionStatusStructInstance.Rows);
结果:
RC is: 0
Long Name is: MAINFRAM
Rows is: 20480
行数应该是24!(在C中我可以看到0x 18 - 0x 00)20480是0x 5000...我做错了什么?
编辑:当我在C中看到正确的LSB时,我有了一个奇怪的想法,将结构的声明从:
Rows: ref.types.uint16, // 13
致:
Rows: ref.types.uchar, // 12
Padding: ref.types.uchar, // 13
现在我有了正确的输出:
RC is: 0
Long Name is: MAINFRAM
Rows is: 24
但是如果uchar是0x 18,uint 16怎么会是0x 5000呢???我什么都不明白!这非常令人沮丧...
1条答案
按热度按时间7uzetpgm1#
是的!我忘了C结构有对齐/打包问题!
使用
ref-struct
,您可以在定义结构时添加第二个参数{packed: true}
...现在输出是正确的!