Javascript 如何获得UInt64的值,toString唯一的方法?

Javascript 如何获得UInt64的值,toString唯一的方法?,javascript,firefox-addon,jsctypes,Javascript,Firefox Addon,Jsctypes,我有这个: “ctypes.UInt64(“7”)” 通过以下方式返回: var chars = SendMessage(hToolbar, TB_GETBUTTONTEXTW, local_tbb.idCommand, ctypes.voidptr_t(0)); 所以 给予 'chars=' 'UInt64 { }' "7" 'ctypes.UInt64("7")' 因此,我可以通过执行chars.toString()来获取该值,但我必须对其运行parseInt,是否仍可以将其作为属性来

我有这个:
“ctypes.UInt64(“7”)”

通过以下方式返回:

var chars = SendMessage(hToolbar, TB_GETBUTTONTEXTW, local_tbb.idCommand, ctypes.voidptr_t(0));
所以

给予

'chars=' 'UInt64 {  }' "7" 'ctypes.UInt64("7")'

因此,我可以通过执行
chars.toString()
来获取该值,但我必须对其运行
parseInt
,是否仍可以将其作为属性来读取?像
chars.UInt64

js ctypes中64位整数的问题是Javascript缺少兼容类型。所有Javascript数字都是IEEE双精度浮点数(
double
),这些数字可以表示。因此,您甚至不应该自己解析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!
如果需要结果,但不确定它是否为32位无符号整数,则可以检测是否正在处理刚刚打包到
Uint64
中的32位无符号整数:

ctypes.UInt64.compare(ctypes.UInt64("7"), ctypes.UInt64("0xffffffff")) < 0
因此,一旦您知道或检测到某个东西将适合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); 
(为了完整性起见,还有
UInt64.hi()
/
Int64.hi()
UInt64.lo()
/
Int64.lo()
来获取实际64位整数的高32位和低32位,并自己进行64位整数数学运算(),但要注意endianess)

PS:SendMessage的返回值是
intptr\u t
not
uintptr\u t
,这在这里很重要,因为
SendMessage(hwnd,TB\u getbuttonext,…)
在失败时可能返回
-1

因此,将所有这些放在一起(未经测试):

var SendMessage=user32.declare(
“SendMessageW”,
ctypes.winapi_abi,
ctypes.intptr\t,
ctypes.voidptr\u t,//HWND
ctypes.uint32\u t,//MSG
ctypes.uintptr\u t,//WPARAM
ctypes.intptr\u t//LPARAM
);
// ...
var chars=SendMessage(hToolbar,TB_getbuttonextw,local_tbb.idCommand,ctypes.voidptr_t(0));
if(ctypes.Int64.compare(chars,ctypes.Int64(“0”))<0){
抛出新错误(“TB_GETBUTTONTEXT返回失败(负值)”;
}
if(ctypes.Int64.comare(chars,ctypes.Int64(“32768”))>0){
抛出新错误(“TB_GETBUTTONTEXT返回了不合理的大数>32KiB”);
}
chars=parseInt(chars.toString());

js ctypes中64位整数的问题在于Javascript缺少兼容类型。所有Javascript数字都是IEEE双精度浮点数(
double
),这些数字可以表示。因此,您甚至不应该自己解析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!
如果需要结果,但不确定它是否为32位无符号整数,则可以检测是否正在处理刚刚打包到
Uint64
中的32位无符号整数:

ctypes.UInt64.compare(ctypes.UInt64("7"), ctypes.UInt64("0xffffffff")) < 0
因此,一旦您知道或检测到某个东西将适合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); 
(为了完整性起见,还有
UInt64.hi()
/
Int64.hi()
UInt64.lo()
/
Int64.lo()
来获取实际64位整数的高32位和低32位,并自己进行64位整数数学运算(),但要注意endianess)

PS:SendMessage的返回值是
intptr\u t
not
uintptr\u t
,这在这里很重要,因为
SendMessage(hwnd,TB\u getbuttonext,…)
在失败时可能返回
-1

因此,将所有这些放在一起(未经测试):

var SendMessage=user32.declare(
“SendMessageW”,
ctypes.winapi_abi,
ctypes.intptr\t,
ctypes.voidptr\u t,//HWND
ctypes.uint32\u t,//MSG
ctypes.uintptr\u t,//WPARAM
ctypes.intptr\u t//LPARAM
);
// ...
var chars=SendMessage(hToolbar,TB_getbuttonextw,local_tbb.idCommand,ctypes.voidptr_t(0));
if(ctypes.Int64.compare(chars,ctypes.Int64(“0”))<0){
抛出新错误(“TB_GETBUTTONTEXT返回失败(负值)”;
}
if(ctypes.Int64.comare(chars,ctypes.Int64(“32768”))>0){
抛出新错误(“TB_GETBUTTONTEXT返回了不合理的大数>32KiB”);
}
chars=parseInt(chars.toString());

Wow非常感谢您。我保证你的努力不会白费,我正在大量使用它,希望能发布到我的插件Profilist,这样其他人也可以使用它。非常感谢你!哦,哇,我对我的
发送消息
做了一个巨大的修改。我使用了
uintptr\u t
我现在将它改为s
intptr\u t
实际上是为了返回
SendMessage
这是否更合适:
ctypes.voidptr\u t.size==8?ctypes.int64\t:ctypes.long
?这当然是可能的。如果是更好的话,我们可以讨论一下。。。这将使编写只支持win32的代码变得更容易,但使编写在32位和64位Firefox上工作的代码变得更难。Windows上有64位Firefox:有64位的Nightlies,还有一些第三方版本,比如Palemon x64。我不想编写忽略这些的代码,如果Windows发行版上有官方的Firefox 64(未来的版本),这会导致代码崩溃,所以我不会使用指针大小的技巧。在带有
ctypes.long
的Win32上,你会得到一个数字,而在带有
ctypes.int64\t
的Win32上,你会得到一个
ctypes.int64
包装的数字。因此,您仍然需要像我的回答中所描述的那样处理64个数字中的数字,但不能处理win32数字,这需要编写两个版本的相同代码,一个版本适用于普通
long
数字,另一个版本适用于wrapped
int64
数字,请测试两个版本是否正常工作。所以,除了更多的工作,你什么也得不到。除非你跳过了64位的部分,否则你的东西将不再是未来的证明。非常感谢。我保证你的努力不会白费我会用的他
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());