又让64位给捉弄了一回
昨天把一个 vc6 下的程序移植到 vc2005 里,用了一上午时间总算是把环境配置,语法不兼容的问题都抹平了。编译通过,调试运行基本正常。然而,直接双击运行,就崩溃掉了。。
通过调用堆栈知道问题出在网络代码方面,最后确定到函数 GetAdaptersInfo 上。
DWORD GetAdaptersInfo(
PIP_ADAPTER_INFO pAdapterInfo,
PULONG pOutBufLen
);
typedef struct _IP_ADAPTER_INFO {
struct _IP_ADAPTER_INFO* Next;
DWORD ComboIndex;
char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];
char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];
UINT AddressLength;
BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];
DWORD Index;
UINT Type;
UINT DhcpEnabled;
PIP_ADDR_STRING CurrentIpAddress;
IP_ADDR_STRING IpAddressList;
IP_ADDR_STRING GatewayList;
IP_ADDR_STRING DhcpServer;
BOOL HaveWins;
IP_ADDR_STRING PrimaryWinsServer;
IP_ADDR_STRING SecondaryWinsServer;
time_t LeaseObtained;
time_t LeaseExpires;
} IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;
在 vc6 下 time_t 是 32 位的,而 vc2005 里默认是 64 位的。
所以 GetAdaptersInfo 这个只支持 32 位的函数返回的数据长度就不对了。
程序编译没有问题,但是运行的时候,对LeaseExpires的访问就出现了不确定性,因为它已经超出 GetAdaptersInfo 所识别的范围了。
MSDN 上说:
On Windows XP and later: Use the GetAdaptersAddresses function instead of GetAdaptersInfo.
但是 GetAdaptersAddresses 无法获取 DHCP分配ip的时间和过期的时间,所以还是得用 GetAdaptersInfo 函数。
在 vc2005 下,一种方法是定义 _USE_32BIT_TIME_T 来强制程序使用 32 位时间,但可能会不太兼容 64 位的系统。另一种方法就是用 __time32_t 替换 time_t 。
参考:
http://msdn.microsoft.com/en-us/library/aa365917(VS.85).aspx
http://msdn.microsoft.com/en-us/library/aa365915(v=VS.85).aspx
http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/fe17ff48-71e4-401b-9982-84addb809eea