1

Qt4 で、ネットワーク アダプターのパラメーターを変更する単純なアプリケーションを作成しました。そのために、次のsetInterfaceParamsように実装された というスロットがあります。

DWORD WinNetInterface::setInterfaceParams(QString index, QString ip, QString netmask, QString gateway)
{
    DWORD res = NULL;
    HINSTANCE lib = (HINSTANCE) LoadLibrary((WCHAR *)"iphlpapi.dll");
    _SetAdapterIpAddress SetAdapterIpAddress = (_SetAdapterIpAddress) GetProcAddress(lib, "SetAdapterIpAddress");

    PWSTR pszGUID = NULL;
    //char  *szGUID = (char *)index.toStdString().c_str();
    QByteArray a = index.toLocal8Bit();
    char  *szGUID = a.data();
    WideCharToMultiByte(CP_ACP, 0, pszGUID, -1, szGUID, sizeof(szGUID), NULL, NULL);


// Method 01
    res = SetAdapterIpAddress(szGUID,
                        0,
                        inet_addr(ip.toStdString().c_str()),
                        inet_addr(netmask.toStdString().c_str()),
                        inet_addr(gateway.toStdString().c_str()));
// End of method 01

// Method 02
    /*res = SetAdapterIpAddress("{422C5689-A17B-402D-A6A2-22CE13E857B5}",
                                0,
                                inet_addr("192.168.1.10"),
                                inet_addr("255.255.255.0"),
                                inet_addr("192.168.1.1"));*/
// End of method 02
    return res;
}

slot に接続されているボタンをクリックするとsetInterfaceParams、セグメンテーション違反が発生します。method01 にコメントしても何も起こりませんが、method02 を使用すると何かが起こります。この関数を単純な C++ アプリケーションで試してみたところ、問題なく動作し、Windows XP SP3 でテストしました。

#include <windows.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <iostream>


typedef DWORD (WINAPI *_SetAdapterIpAddress )(char *szAdapterGUID, 
                                              DWORD dwDHCP, 
                                              DWORD dwIP, 
                                              DWORD dwMask, 
                                              DWORD dwGateway); 


int main()
{
    HINSTANCE lib = (HINSTANCE) LoadLibrary("iphlpapi.dll"); 
    _SetAdapterIpAddress SetAdapterIpAddress = (_SetAdapterIpAddress) GetProcAddress(lib, "SetAdapterIpAddress");

    PWSTR pszGUID = NULL;
    char  szGUID[] = "{422C5689-A17B-402D-A6A2-22CE13E857B5}";
    DWORD dwSize = 0;
    WideCharToMultiByte(CP_ACP, 0, pszGUID, -1, szGUID, sizeof(szGUID), NULL, NULL);

    DWORD res = SetAdapterIpAddress(szGUID, 
                        0, 
                        inet_addr("192.168.1.10"),
                        inet_addr("255.255.255.0"),
                        inet_addr("192.168.1.1"));

    std::cout << res;                   

    return 0;
}
4

1 に答える 1

1
LoadLibrary((WCHAR *)"iphlpapi.dll");

それは機能しません。リテラル文字列は 8 ビットであり、実際の変換なしでキャストしても幅が広くならないため、dll の読み込みに失敗した可能性があります。

TEXTWinAPI 関数に渡されるほとんどのリテラル文字列の前後にまたはマクロを使用_Tして、コンパイル オプションに応じて正規またはワイドにする必要があります。

LoadLibrary(_T("iphlpapi.dll"));

どちらかLoadLibrary("iphlpapi.dll");またはに変換されますLoadLibrary(L"iphlpapi.dll");

また、呼び出しが失敗した場合は NULL を返す 関数LoadLibraryと関数によって返される値を常にチェックする必要があります。GetProcAddress

于 2012-07-07T12:24:45.623 に答える