将指针转换为 ULONG_PTR 以进行在 32 位和 64 位系统中兼容的指针运算?

Casting pointer to ULONG_PTR to do pointer arithmetic that is compatible in 32 bit and 64 systems?

我正在编写一个执行一些指针运算的内核模式驱动程序,首先我得到一个指向内存中 PE 模块一部分的 PVOID 指针,然后我需要向它添加一个偏移量并以某种方式编译它适用于 32 位和 64 位系统。

转换为 INT 或 UINT 将不起作用,因为众所周知,它们在 64 位系统中仍然是 32 位的,因此在 64 位系统中转换地址将导致问题。

所以现在我正在将地址转换为 ULONG_PTR,这似乎是 Microsoft 的建议:

https://docs.microsoft.com/en-us/windows/win32/winprog64/rules-for-using-pointers

然后对其进行运算并得到新地址。

我这样做是不是最好的方式,或者除了 ULONG_PTR 之外还有更好的选择吗?因为我没有很多将地址转换为 ULONG_PTR.

的示例代码

通过将 64/32 位 PVOID 地址转换为 ULONG_PTR 对其进行算术运算,我会遇到任何问题吗?

基本上我想将地址转换为某种类型,在 32 位系统中为 32 位,在 64 位系统中为 64 位并且是无符号的,并允许我对地址进行算术运算,并寻找最佳选择将我的 PVOID 投射到。

C 标准方法是强制转换为 uintptr_t;但如果您想与 Microsoft 代码保持一致,您可以使用他们的非标准 typedef。

当谈到用偏移量做算术时,普遍的看法是编译器可以跟踪出处即使是整数,所以如果你将 void * 转换为 uintptr_t 并操作结果value 以便它指向另一个完全不属于原始 allocation/object 的对象并将其转换回 void * 然后行为将是未定义的(例如参见 [​​=14=]),但我很确保每个人都在低级编程中这样做,并且相信 Microsoft 编译器不会以这种方式跟踪指针出处。