从32bit迁移到64bit

作为试验田,SolidMCP从来只有Win32/Debug配置。在拥有了一台12G Memory的牛机之后,再没有不支持X64配置的理由。

>> __tmainCRTStartup

 其实无关于X64或者Win32,只不过碰到了,记录下来。

-----------------------------------------------------------------------------------------

Linking...
libcmtd.lib(wincrt0.obj) : error LNK2019: unresolved external symbol WinMain referenced in function __tmainCRTStartup
\Lib\Debug_x64\SolidMCP_CodeFormat_ConvertEncoding.exe : fatal error LNK1120: 1 unresolved externals

-----------------------------------------------------------------------------------------
Solution:

把Subsystem从windows/SUBSYSTEM:WINDOWS改成CONSOLE就好了。

>>Project Settings中的"_Win32"

需要注意的是"_win32"只是与"_win16"相对应的,对于Windows 32/64 bit来说,是一样的。至于为什么这样,不清楚,可能是为了兼容性把.

如果你要判断是Windows 32bit还是64bit, 可以这样干:

#define SMCP_PLATFORM_NAME_WIN32 "Microsoft Windows 32 bit"
#define SMCP_PLATFORM_NAME_AMD64 "Microsoft Windows 64 bit (AMD)"
#define SMCP_PLATFORM_NAME_IA64 "Microsoft Windows 64 bit (Itanium)"

#ifdef _M_IX86
# define SMCP_PLATFORM_NAME SMCP_PLATFORM_NAME_WIN32
#elif _M_AMD64
# define SMCP_PLATFORM_NAME SMCP_PLATFORM_NAME_AMD64
#elif _M_IA64
# define SMCP_PLATFORM_NAME SMCP_PLATFORM_NAME_IA64
#else
# error
"Unknown Architecture detected"
#endif

>> 注册表

在一切准备好之前,还是让我的Win32程序跑在64bit的牛机上。把我的Registry文件先跑了一遍,做一些配置:

--------------------------------------------------------------------

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\SolidMCP]

[HKEY_LOCAL_MACHINE\SOFTWARE\SolidMCP\Applets]

[HKEY_LOCAL_MACHINE\SOFTWARE\SolidMCP\Applets\S2D]

[HKEY_LOCAL_MACHINE\SOFTWARE\SolidMCP\Applets\S2D\Info]
"FileName"="SMCPApp_S2D.dll"
"DisplayName"="SolidMCP.S2D"

[HKEY_LOCAL_MACHINE\SOFTWARE\SolidMCP\Applets\S2D\Preference]

[HKEY_LOCAL_MACHINE\SOFTWARE\SolidMCP\Applets\S3D]

[HKEY_LOCAL_MACHINE\SOFTWARE\SolidMCP\Applets\S3D\Info]
"DisplayName"="SolidMCP.S3D"
"FileName"="SMCPApp_S3D.dll"

[HKEY_LOCAL_MACHINE\SOFTWARE\SolidMCP\Applets\S3D\Preference]
"Path"=""

[HKEY_LOCAL_MACHINE\SOFTWARE\SolidMCP\General]

--------------------------------------------------------------------

居然程序有错,debug一把,问题就在于找不到HKEY_LOCAL_MACHINE\SOFTWARE\SolidMCP\Applets。

愣了一把,猜想到这是64bit下32bit程序的注册表有些猫腻,他们都在Wow6432Node之下。

所以专门为64bit的32bit SolidMCP搞了一些新的reg文件。

--------------------------------------------------------------------

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\SolidMCP]

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\SolidMCP\Applets]

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\SolidMCP\Applets\S2D]

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\SolidMCP\Applets\S2D\Info]
"FileName"="SMCPApp_S2D.dll"
"DisplayName"="SolidMCP.S2D"

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\SolidMCP\Applets\S2D\Preference]

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\SolidMCP\Applets\S3D]

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\SolidMCP\Applets\S3D\Info]
"DisplayName"="SolidMCP.S3D"
"FileName"="SMCPApp_S3D.dll"

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\SolidMCP\Applets\S3D\Preference]
"Path"=""

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\SolidMCP\General]

--------------------------------------------------------------------

碰到的第二个问题就是Automatic Build script失效,这是一个python脚本,通过调用Incredibuild来编译整个工程,切换到X64之后也是不能工作,道理跟上面的一样。

因为脚本是通过注册表来搜索Incredibuild的安装路径的。

结论:

在Windows X64系统中的Win32程序,注册表在Wow6432Node之下。

而最终还是要搞成XML/YAML配置,便于扩展或跨平台。

>> C4244 – conversion from ‘type1’ to ‘type2’, possible loss of data

MSDN:

An integer type is converted to a smaller integer type. This is a level-4 warning if type1 is int and type2 is smaller than int. Otherwise, it is a level 3 (assigned a value of type __int64 to a variable of type unsigned int). A possible loss of data may have occurred.

If you get C4244, you should either change your program to use compatible types, or add some logic to your code, to ensure that the range of possible values will always be compatible with the types you are using.

>> C4311 - pointer truncation from 'type' to 'type'

MSDN:

This warning detects 64-bit portability issues. For example, if code is compiled on a 64-bit platform, the value of a pointer (64 bits) will be truncated if it is assigned to an int (32 bits).

This warning is only issued when /Wp64 is used. See /Wp64 for more information. Also, see Rules for Using Pointers

// C4311.cpp
// compile with: /W1 /Wp64
#include <stddef.h>
int main() {
void* p = &p;
unsigned
long i = (unsigned long)p; // C4311
intptr_t j = (<span style="color: #ff00ff;">intptr_t</span>)p; // OK
}

>>  C4312 - conversion from 'type1' to 'type2' of greater size

MSDN:

This warning detects 64-bit portability issues. You attempted to assign a 32-bit value to a 64-bit type. For example, casting a 32-bit int or 32-bit long to a 64-bit pointer.

This can be an unsafe conversion in some circumstances when sign extension occurs. If a negative number is assigned to a pointer type of a size greater than the int, sign extension will occur and the pointer value will refer to a memory address different from the value of the int.

This warning is only issued when /Wp64 is used. See /Wp64 for more information. Also, see Rules for Using Pointers.

// C4312.cpp
// compile with: /W1 /Wp64 /LD
void* f(int i) {
return (void*)i; // C4312
}

// OK
void* f2(__int64 i) {
return (void*)i;
}

posted on 2011-07-04 17:36  飘行天下  阅读(1109)  评论(0编辑  收藏  举报

导航