Ошибка сегментации при смене шлюза по умолчанию
Я написал простое приложение на 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;
}
Когда я нажимаю на кнопку, которая подключена к слоту 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;
}
1 ответ
LoadLibrary((WCHAR *)"iphlpapi.dll");
Это не может работать, литеральная строка в 8 битах, приведение ее без реального преобразования не делает ее широкой, поэтому загрузка dll, вероятно, не удалась.
Вы должны использовать TEXT
или же _T
макрос вокруг большинства литеральных строк, передаваемых в функции WinAPI, чтобы сделать их регулярными или широкими в зависимости от параметров компиляции:
LoadLibrary(_T("iphlpapi.dll"));
который будет переводить либо LoadLibrary("iphlpapi.dll");
или же LoadLibrary(L"iphlpapi.dll");
,
Также вы всегда должны проверять значение, возвращаемое LoadLibrary
а также GetProcAddress
функции, которые возвращают NULL, если вызов не выполнен.