Я знаю, что могу использовать правильно функцию WinApi DsGetDcName
вот так:
DOMAIN_CONTROLLER_INFO* dcInfo = nullptr;
unsigned long res = ::DsGetDcName(nullptr,
nullptr,
nullptr,
nullptr,
0, &dcInfo);
Это неестественно, я знаю, но я хочу понять, почему нельзя писатьэто также выглядит так:
void* dcInfo = nullptr;
unsigned long res = ::DsGetDcName(nullptr,
nullptr,
nullptr,
nullptr,
0, (DOMAIN_CONTROLLER_INFO**) dcInfo);
if (res)
{
wchar_t* name;
name = static_cast<DOMAIN_CONTROLLER_INFO*> (dcInfo)->DomainControllerName;
}
Вторая версия использует void*
в качестве типа указателя, и именно поэтому я получаю нарушение доступа при его запуске (при вызове ::DsGetDcName
).Но я не понимаю, почему это?Связано ли это с тем, как память выравнивается при указании void*
для dcInfo
, а не с типом DOMAIN_CONTROLLER_INFO* dcInfo
?
РЕШЕНИЕ
НахожуИз проблемы я могу использовать версию свернутый небезопасный void *, я просто не передал правильный адрес указателя этой функции.Вот оно:
void* dcInfo = nullptr;
unsigned long res = ::DsGetDcName(nullptr,
nullptr,
nullptr,
nullptr,
0, (DOMAIN_CONTROLLER_INFO**) &dcInfo);
Обратите внимание, что я передаю (DOMAIN_CONTROLLER_INFO**) &dcInfo
вместо (DOMAIN_CONTROLLER_INFO**) dcInfo
.Раньше я просто закрывал ногу, потому что сказал компилятору, что знаю, что делаю, но передал функции значение указателя вместо необходимого адреса указателя (и да, это значение указателя было nullptr
):-))
Это еще одна причина использовать правильную версию (версия 1).Во втором случае также недостатком является то, что вы должны снова разыграть результат, подобный следующему:
wchar_t* name;
name = static_cast<DOMAIN_CONTROLLER_INFO*>(dcInfo)->DomainControllerName; // Get DC