Безопасно ли использование.NET WSAStartup для 64-битных приложений?
Существует несоответствие между версией.NET Framework и собственной версией Win32 структуры WSAData для 64-битных приложений, поскольку порядок полей различен. Я скопировал версию.NET для использования в нашем продукте на C#, и коллега обеспокоен тем, что я вызвал повреждение памяти. Есть ли риск повреждения памяти из-за этого несоответствия при использовании DllImport / PInvoke? Есть ли риск неправильного доступа к памяти при маршалинге нативной версии в управляемую? Предположим, меня не интересует фактический доступ к полям результирующего объекта WSAData. Я просто хочу быть уверен, что мой вызов WSAStartup не повредит память и не приведет к сбою приложения.
Вот родная версия C++ в WinSock2.h. Обратите внимание, что порядок членов отличается в 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
);
2 ответа
Конечно, это неправильно..NET Framework сходит с рук, размеры структур по-прежнему правильны (400 байт в 32-разрядном режиме, 408 в 64-разрядном режиме), поэтому повреждение памяти не может произойти. И он на самом деле не использует никакую возвращаемую информацию, они наверняка поймали бы ошибку, если бы сделали.
Вы можете отправить сообщение об ошибке на 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 один (CharSet=CharSet.Ansi
), и каждый символ Анси является юридическим символом в Юникоде.