又让64位给捉弄了一回


又让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