Я использовал Статья Павла Йосифовича для разработки драйвера ядра Windows с использованием c ++ (не по особой причине, просто для его изучения).
В своей статье Павел показывает, как перегрузитьоператоры new и delete и как реализовать вектор.
, когда я попытался скомпилировать драйвер с перегруженным оператором удаления, произошел сбой из-за ошибки компоновщика (LNK2019), которая возникла из-за того, что компилятор не скомпилировал правильный оператор удаления.
мой код:
Vector<ULONG> *vector = nullptr;
void* __cdecl operator new(size_t size, POOL_TYPE pool, ULONG tag = 0) {
return ExAllocatePoolWithTag(pool, size, tag);
}
void __cdecl operator delete(void* p) {
ExFreePool(p);
}
NTSTATUS Init()
{
vector = (Vector<ULONG>*)new(NonPagedPool, 'DaOr') Vector<ULONG>();
return STATUS_SUCCESS;
}
NTSTATUS Fin()
{
// case 1:
delete vector;
// case 2:
// delete (void*)vector;
return STATUS_SUCCESS;
}
В двух случаях сообщения об ошибках компоновщика приводили к следующему:
Ошибка в случае 1: (в этом случае зависание надОператор удаления в Fin () показал мне, что это НЕ мой перегруженный оператор удаления "оператор void delete (void *, unsigned int)" (VS2017)).
Ошибка LNK2019неразрешенный внешний символ «void __cdecl operator delete (void *, unsigned int)» (?? 3 @ YAXPAXI @ Z), на который ссылается функция «public: void * __thiscall Vector ::` скалярное удаление деструктора '(unsigned int) »(?? _ G? $ Vector @ K @@ QAEPAXI @ Z) * 1019 *
Ошибка в случае 2: (в этом случае при наведении курсора на оператор удаления в Fin () мне показалось, что это моя перегруженнаяоператор удаления "оператор void delete (void * p)" (VS2017)).
Ошибка LNK2019, неразрешенный внешний символ "оператор void __cdecl delete (void *, unsigned int)"(?? 3 @ YAXPAXI @ Z) упоминается в функции "long __stdcall Fin (void)" (? Fin @@ YGJXZ)
В обоих случаях кажется, что компоновщик ищет одно и то же удалениеоператор только оператор удаления ссылается из разных мест.
Проблема была решена путем изменения подписи моего оператора удаления:
с
void __cdecl operator delete(void*)
на
void __cdecl operator delete(void*, unsigned int)
компилятор определяет мой оператор удаления.
Мои вопросы:
почему в случае 1компоновщик искал оператор удаления в векторе?Я могу как-то понять путаницу компилятора в том, что он пытался вызвать деструктор Vector - но мне хотелось бы объяснения.
Почему в случае 2 при наведении курсора на оператор удаленияв Fin () он показывает «оператор delete (void *)», но ошибка показывает «оператор delete (void *, unsigned int)»?(Я знаю, что это может быть ошибка VS2017, но может ли это быть чем-то еще?)
почему в обоих случаях я передаю только один параметр для удаления, и все же он идентифицирует «оператор удаления»(void *, unsigned int) "как если бы я отправил ему два параметра, а не" operator delete (void *) ", как должно быть?