对于 64 位应用程序,.NET Framework 版本和 native Win32 版本的 WSAData 结构不匹配,因为字段的顺序不同。我复制了用于我们基于 C# 的产品的 .NET 版本,一位同事担心我导致了内存损坏。使用 DllImport/PInvoke 时是否存在由于这种不匹配而导致内存损坏的风险?将 native 版本编码到托管版本时是否存在无效内存访问的风险?假设我不关心实际访问生成的 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;
这是 managed version in the .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 字节),因此不会发生内存损坏。而且它实际上并没有使用任何返回的信息,如果他们这样做的话,他们肯定会发现错误。
您可以在 connect.microsoft.com 上提交错误,但我怀疑他们会急于修复它。
关于c# - 对于 64 位应用程序,.NET 使用 WSAStartup 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29198807/