Noi*_*art 1 javascript firefox-addon jsctypes
我有这个:
"ctypes.UInt64("7")"
它是由这个返回的:
var chars = SendMessage(hToolbar, TB_GETBUTTONTEXTW, local_tbb.idCommand, ctypes.voidptr_t(0));
Run Code Online (Sandbox Code Playgroud)
所以
console.log('chars=', chars, chars.toString(), uneval(chars));
Run Code Online (Sandbox Code Playgroud)
给
'chars=' 'UInt64 { }' "7" 'ctypes.UInt64("7")'
Run Code Online (Sandbox Code Playgroud)
所以我可以通过 go 来获取值chars.toString(),但我必须在上面运行一个parseInt,反正有没有像属性一样读取它?喜欢chars.UInt64?
js-ctypes 中 64 位整数的问题在于 Javascript 缺乏兼容类型。所有 Javascript 数字都是 IEEE 双精度浮点数 ( double),它们最多可以表示53 位整数。因此,您甚至不应该尝试自己解析 int,除非您知道结果适合double. 例如,您无法通过指针知道这一点。
例如,考虑以下事项:
// 6 * 8-bit = 48 bit; 48 < 53, so this is OK
((parseInt("0xffffffffffff", 16) + 2) == parseInt("0xffffffffffff", 16)) == false
// However, 7 * 8-bit = 56 bit; 56 < 53, so this is not OK
((parseInt("0xffffffffffffff", 16) + 2) == parseInt("0xffffffffffffff", 16)) == true
// Oops, that compared equal, because a double precision floating point
// cannot actual hold the parseInt result, which is still well below 64-bit!
Run Code Online (Sandbox Code Playgroud)
让我们正确处理 JS 中的 64 位整数......
如果您只想比较,请使用UInt64.compare()/ Int64.compare(),例如
// number == another number
ctypes.UInt64.compare(ctypes.UInt64("7"), ctypes.UInt64("7")) == 0
// number != another number
ctypes.UInt64.compare(ctypes.UInt64("7"), ctypes.UInt64("6")) != 0
// number > another number
ctypes.UInt64.compare(ctypes.UInt64("7"), ctypes.UInt64("6")) > 0
// number < another number
ctypes.UInt64.compare(ctypes.UInt64("7"), ctypes.UInt64("8")) < 0
Run Code Online (Sandbox Code Playgroud)
如果您需要结果,但不确定它是一个 32 位无符号整数,您可以检测您是否正在处理刚刚打包到的 32 位无符号整数Uint64:
ctypes.UInt64.compare(ctypes.UInt64("7"), ctypes.UInt64("0xffffffff")) < 0
Run Code Online (Sandbox Code Playgroud)
以及 中 32 位有符号整数的模拟Int64,但您需要比较最小值和最大值:
ctypes.Int64.compare(ctypes.Int64("7"), ctypes.Int64("2147483647")) < 0 &&
ctypes.Int64.compare(ctypes.Int64("7"), ctypes.Int64("-2147483648")) > 0
Run Code Online (Sandbox Code Playgroud)
因此,一旦您知道或检测到某些内容适合 JS double,就可以安全地调用parseInt它。
var number = ...;
if (ctypes.UInt64.compare(number, ctypes.UInt64("0xffffffff")) > 0) {
throw Error("Whoops, unexpectedly large value that our code would not handle correctly");
}
chars = parseInt(chars.toString(), 10);
Run Code Online (Sandbox Code Playgroud)
(为了完整起见,还有UInt64.hi()/Int64.hi()和UInt64.lo()/Int64.lo()来获取真实 64 位整数的高和低 32 位并自己进行 64 位整数数学运算(例如),但要注意字节序)。
PS:的返回值SendMessage是intptr_t不是uintptr_t,这是很重要的,因为在这里SendMessage(hwnd, TB_GETBUTTONTEXT, ...)可能会返回-1失败!
所以把所有这些放在一起(未经测试):
var SendMessage = user32.declare(
'SendMessageW',
ctypes.winapi_abi,
ctypes.intptr_t,
ctypes.voidptr_t, // HWND
ctypes.uint32_t, // MSG
ctypes.uintptr_t, // WPARAM
ctypes.intptr_t // LPARAM
);
// ...
var chars = SendMessage(hToolbar, TB_GETBUTTONTEXTW, local_tbb.idCommand, ctypes.voidptr_t(0));
if (ctypes.Int64.compare(chars, ctypes.Int64("0")) < 0) {
throw new Error("TB_GETBUTTONTEXT returned a failure (negative value)");
}
if (ctypes.Int64.comare(chars, ctypes.Int64("32768")) > 0) {
throw new Error("TB_GETBUTTONTEXT returned unreasonably large number > 32KiB");
}
chars = parseInt(chars.toString());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2582 次 |
| 最近记录: |