Компилятор не может определить перегруженный оператор удаления, вызывающий LNK2019 - PullRequest
0 голосов
/ 27 мая 2018

Я использовал Статья Павла Йосифовича для разработки драйвера ядра 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. почему в случае 1компоновщик искал оператор удаления в векторе?Я могу как-то понять путаницу компилятора в том, что он пытался вызвать деструктор Vector - но мне хотелось бы объяснения.

  2. Почему в случае 2 при наведении курсора на оператор удаленияв Fin () он показывает «оператор delete (void *)», но ошибка показывает «оператор delete (void *, unsigned int)»?(Я знаю, что это может быть ошибка VS2017, но может ли это быть чем-то еще?)

  3. почему в обоих случаях я передаю только один параметр для удаления, и все же он идентифицирует «оператор удаления»(void *, unsigned int) "как если бы я отправил ему два параметра, а не" operator delete (void *) ", как должно быть?

...