[英]Is the .NET use of WSAStartup safe for 64-bit apps?
對於64位應用程序,.NET Framework版本與WSAData結構的本機Win32版本之間存在不匹配,因為字段的順序不同。 我復制了.NET版本以用於我們基於C#的產品,同事擔心我已經導致內存損壞。 使用DllImport / PInvoke時,由於這種不匹配,是否存在內存損壞的風險? 將本機版本封送到托管版本時是否存在無效內存訪問風險? 我們假設我並不關心實際訪問生成的WSAData對象的字段。 我只是想確定我對WSAStartup的調用不會破壞內存或使應用程序崩潰。
這是WinSock2.h中的本機C ++版本。 請注意,成員的順序在64位與32位之間是不同的。 WSADESCRIPTION_LEN為256,WSASYS_STATUS_LEN為128。
typedef struct WSAData {
WORD wVersion;
WORD wHighVersion;
#ifdef _WIN64
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR * lpVendorInfo;
char szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYS_STATUS_LEN+1];
#else
char szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYS_STATUS_LEN+1];
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR * lpVendorInfo;
#endif
} WSADATA, FAR * LPWSADATA;
以下是.NET Framework中的托管版本 :
[StructLayout(LayoutKind.Sequential)]
internal struct WSAData {
internal short wVersion;
internal short wHighVersion;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=257)]
internal string szDescription;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=129)]
internal string szSystemStatus;
internal short iMaxSockets;
internal short iMaxUdpDg;
internal IntPtr lpVendorInfo;
}
[DllImport(WS2_32, CharSet=CharSet.Ansi, BestFitMapping=false,
ThrowOnUnmappableChar=true, SetLastError=true)]
internal static extern SocketError WSAStartup(
[In] short wVersionRequested,
[Out] out WSAData lpWSAData
);
當然,這是不正確的。 .NET Framework摒棄它,結構大小仍然正確(32位模式下為400字節,64位模式下為408),因此不會發生內存損壞。 它實際上並沒有使用任何返回的信息,如果他們這樣做,他們肯定會抓住這個bug。
您可以在connect.microsoft.com上提交錯誤,我懷疑他們是否會急着解決它。
是的,結構錯誤......您可以使用錯誤的結構和正確的結構進行測試:
[StructLayout(LayoutKind.Sequential)]
internal struct WSAData
{
internal short wVersion;
internal short wHighVersion;
internal short iMaxSockets;
internal short iMaxUdpDg;
internal IntPtr lpVendorInfo;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 257)]
internal string szDescription;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 129)]
internal string szSystemStatus;
}
WSAData data;
int res = WSAStartup(2 << 8 | 2, out data);
Console.WriteLine("64bits: {0}, Result = {1}, szDescription: {2}, szSystemStatus: {3}", Environment.Is64BitProcess, res, data.szDescription, data.szSystemStatus);
但是你沒有任何問題,因為.NET可能不會使用所有這些不同的字段(它需要什么描述?)甚至沒有Unicode轉換的問題,因為使用的方法是Ansi one( CharSet=CharSet.Ansi
),每個Ansi字符都是Unicode中的合法字符。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.