如何在 MSVC C++中迁移 x64 的 x86 代码
How to migrate x86 code for x64 in MSVC C++
我有一个针对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 变量大小更改为 8bytes(64 位(。在 MSVC 中,我可以这样做吗?我可以将所有保存地址的变量更改为 64 位变量,但这是一个很大的库,因此需要对其进行深入测试以确保它与 x86 构建一样正常工作。任何建议将不胜感激。
在 GCC 中,我记得可以使用编译器选项将 int 变量大小更改为 8bytes(64 位(。
如果可以,最好不要这样做,其他代码/库可能不会预料到它。对于标头尤其如此,您不应该强制库的使用者依赖编译器标志。
我可以将所有保存地址的变量更改为 64 位变量,但这是一个很大的库,因此需要对其进行深入测试以确保它与 x86 构建一样正常工作。
如果写错了,这是您只需要处理的事情。还有很多其他陷阱,许多意外的内存覆盖和截断可能会被忽视,直到不幸的一天。
C 和 C++ 具有 typedef,这对于控制平台特定方面以及明确意图很有用(例如,我知道对uintptr_t
的期望,我甚至不希望long long
成为指针(。
确保你打开了所有的警告,我发现检查Windows/MSVC和Linux/GCC可以帮助发现一些事情,因为警告略有不同。例如:
int y = (int)ptr;
警告 C4311:"类型转换":指针从"int *"截断为"int">
首先,永远不要将指针转换为任何 int 类型,int
、long
、unsigned
等等。在你必须这样做的地方,有uintptr_t
和intptr_t
它们将具有正确的大小,其他库/API 在使用 API 时可能有自己的类型可以使用(例如LONG_PTR
在 Windows 中(,这应该可以帮助您支持他们正确执行的所有平台。
此外,由于没有什么是完美的,您使用的其他库和 API 可能需要完全不同的函数,例如,无论您使用任何 typedefs,Windows APISetWindowLong
都无法处理 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
这取决于您的需求,这里有两个可能的选项:
- 如果您需要对地址执行按位操作:使用
uintptr_t
而不是int
,这将使您的代码可以通过不同的平台移植。 - 如果您不需要对地址执行按位运算:
void*
而不是int
就可以了。
我假设这段代码是 C(你不应该在 C++ 中以这种方式处理多态性和内存分配(。
- 为x86而非x64编译时出错
- 如何在 MSVC C++中迁移 x64 的 x86 代码
- 将内联程序集尾调用函数尾声替换为用于x86/x64 msvc的Intrinsics
- 将程序从x86转换为x64
- 将vector<vector<double>>从x86平台中创建的一个进程发送到x64中构建的另一个进程的最快方法是什么
- 现代C++中STL API的差异(当我在VS2017中将目标从x64切换到x86时)
- 在x64进程中调用x86 winapi函数
- 致命错误LNK1112:在 npm 安装期间,模块计算机类型'X86'与目标计算机类型'x64'冲突
- 在构建服务器上将 dll C++生成到两个平台 (x86+x64)
- C DLL通过C#UWP应用程序中的Win运行时组件适用于ARM,但对于X86/X64不适用于
- VC++ 异常处理在 x86 和 x64 上对于 IBPP / Firebird 客户端有所不同
- LNK2001在X64环境中的编译代码上看到的错误.但是,该代码在X86环境中填充了罚款
- Return value of std::hash ofr (x86/x64)
- 致命错误LNK1112:通过 vcvarsall .bat x86 运行构建'X86'模块计算机类型'x64'与目标计算机类型冲突
- 如何在 x86 和 x64 平台之间使用 boost::序列化
- VS2012 如何将 C# 的 AnyCPU 配置的输出目录设置为各自解决方案配置的 x86 和 x64 文件夹?
- QtGui4.lib(QtGui4.dll):致命错误LNK1112:模块计算机类型"X86"与目标计算机类型"x64"冲突
- MSVC 2013正在x64内部版本中加载x86系统库
- NtQueryInformationThread for both x86 and x64
- 使用c++以及x86和x64体系结构访问处理器中断