Pinvoke / 从 C# 调用本机 Windows API 函数

Pinvoke / call native Windows API function from C#

在我的 C# 应用程序中,我使用了外部 DLL 的函数。此 DLL 本身使用网络功能。所以有必要从我的 C# 应用程序中初始化 Winsock,让网络套接字为这个 DLL 工作。这就是我尝试执行 WSAStartup 进行初始化的方式,但它似乎不起作用:

class Program
{
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    internal struct WSAData
    {
        internal Int16 version;
        internal Int16 highVersion;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 257)]
        internal String description;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 129)]
        internal String systemStatus;

        internal Int16 maxSockets;
        internal Int16 maxUdpDg;
        internal IntPtr vendorInfo;
    }

    [DllImport("ws2_32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    static extern Int32 WSAStartup(Int16 wVersionRequested, out WSAData wsaData);

    static void Main(string[] args)
    {
        WSAData wsaData;

        wsaData.version = 0;
        wsaData.highVersion = 0;
        WSAStartup(0,out wsaData); // to initialise windows socket

        ... // calling external DLL functions
    }
}

WSAStartup() 似乎调用成功,但使用的DLL 仍然无法访问网络。所以似乎 WSAStartup() 由于某种原因没有工作。知道我在这里做错了什么吗?

亲切的问候

迈克尔

您必须将 2 << 8 | 2 作为第一个参数传递(它是从 WSA 请求的版本)

请注意,Microsoft 生成的签名中存在一个小错误(请参阅),但这不是问题,因此您可以忽略它。

您应该始终检查您调用的 API 函数的 return 值:

int resp = WSAStartup(2 << 8 | 2, out wsaData); // to initialise windows socket

if (resp != 0)
{
    // Error
}

从技术上讲,Microsoft 在 https://msdn.microsoft.com/library/windows/desktop/ms742213.aspx 中建议的检查更为复杂,因为他们这样做:

if (resp != 0 || wsaData.version != (2 << 8 | 2))
{
    // Error
}