C++ 如何在MSVC C+中迁移x64的x86代码+;

C++ 如何在MSVC C+中迁移x64的x86代码+;,c++,migration,64-bit,C++,Migration,64 Bit,我有一个针对x86的旧库。我需要将其迁移到与x64一起使用。但也有一些指针解决问题。为x64编译时,我丢失了指针地址。例如: int main() { struct MY_STRUCT *p; p = (struct MY_STRUCT *)malloc(sizeof(struct MY_STRUCT )); int hnd = (int)p; //at this point, it tries to assign 64 bit address to a 32 bit

我有一个针对x86的旧库。我需要将其迁移到与x64一起使用。但也有一些指针解决问题。为x64编译时,我丢失了指针地址。例如:

int main()
{
    struct MY_STRUCT *p;
    p = (struct MY_STRUCT *)malloc(sizeof(struct MY_STRUCT )); 
    int hnd = (int)p;  //at this point, it tries to assign 64 bit address to a 32 bit variable. So half of the address is gone.
    int ret;
    ret=someFunct(hnd);
}

int someFunct(int Handle)
{
    struct MY_STRUCT *p;
    p = (struct MY_STRUCT *)(Handle); //at this point, p pointer takes an address value like 0x0000000012345678. And this causes access violation exception as expected.

    return 0;
}

在GCC中,我记得int变量大小可以通过编译器选项更改为8字节(64位)。在MSVC中,我可以这样做吗?我可以将所有保存地址的变量更改为64位变量,但这是一个很大的库,因此需要对其进行深入测试,以确保其正常工作,与x86的构建一样。任何建议都将不胜感激。

这取决于您的需要,这里有两种可能的选择:

  • 如果您需要对地址执行逐位操作:使用
    uintptr\t
    而不是
    int
    ,这将使您的代码可以在不同的平台上移植
  • 如果您不需要对地址执行逐位操作:
    void*
    而不是
    int
    就可以了
我假设这段代码是C(在C++中不应该以这种方式处理多态性和内存分配)

在GCC中,我记得int变量大小可以通过编译器选项更改为8字节(64位)

如果可以,最好不要这样做,其他代码/库可能不会期望这样做。对于头文件来说尤其如此,您不应该强迫库的使用者依赖编译器标志

我可以将所有保存地址的变量更改为64位变量,但这是一个很大的库,因此需要对其进行深入测试,以确保其正常工作,与x86的构建一样

如果写错了,你就必须处理这个问题。还有很多其他的陷阱,很多意外的内存覆盖和截断可能会被忽略,直到不幸的一天

C++和C++有TyPoFF,它可以用于控制平台特定的方面,并且使意图明确(例如,我知道从代码< uutpTrtUT中期待什么,并且我甚至不希望将<代码>长Lo/Eng>作为指针)。 确保打开了所有警告,我发现在Windows/MSVC和Linux/GCC上检查有助于发现由于警告略有不同而导致的一些问题。例如:

int y = (int)ptr;
警告C4311:“类型转换”:指针从“int*”截断为“int”

首先,切勿将指针转换为任何int类型,
int
long
unsigned
,等等。在您必须这样做的地方,有大小正确的
uintpr\u t
intptr\u t
,其他库/API在使用API时可能有自己的类型(例如,Windows中的
LONG\u PTR
),这应该可以帮助您支持它们正确执行的所有平台

此外,因为没有什么是完美的,所以您使用的其他库和API可能需要完全不同的函数,例如,Windows API
SetWindowLong
无法处理64位上的指针大小的值,而不管您使用的是什么类型的定义,但Microsoft添加了一个可以容纳指针的
SetWindowLongPtr
函数

SetWindowLong(window, GWL_USERDATA, (LONG)ptr); // Not going to work on 64bit
SetWindowLong(window, GWL_USERDATA, (uintptr_t)ptr); // Still not going to work
SetWindowLongPtr(window, GWL_USERDATA, (LONG_PTR)ptr); // works on 32bit and 64bit

如果代码不符合标准,这就是缺点。。。提示:有<代码> IpTrpRt。更糟糕的是,在C++中,几乎不应该使用<代码> MalOC 分配对象,在使用结构名时,不需要<代码>结构> <代码>关键字。所有的C风格转换都应该立即被视为一个标志,表明有非常糟糕的事情正在发生。独立于迁移代码,您应该首先修复它<代码>int hnd=(int)p从来都不是一个好主意,有一段时间它可能不受欢迎,如果有更多类似这样的代码,那么您需要与您的技术负责人和项目管理人员进行讨论,因为在考虑移植或迁移之前,代码首先需要进行重大重构以使其正确。这是无效代码。@formerlyknownas_463035818伙计,我完全同意你的观点,但我没有开发那个库。