编译器无法识别导致LNK2019的重载删除操作符

时间:2018-05-27 20:42:57

标签: c++ compilation linker visual-studio-2017

我使用Pavel Yosifovich's article使用c ++开发一个Windows内核驱动程序(不是出于特殊原因,只是为了研究它)。

在他的文章中,Pavel展示了如何重载new和delete运算符以及如何实现vector。

当我尝试使用重载的删除操作符编译驱动程序时,由于链接器错误(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()中的删除操作符上向我显示它不是我的重载删除操作符&#34; void operator delete(void *,unsigned int)& #34; (VS2017))。

  

错误LNK2019未解析的外部符号&#34; void __cdecl运算符   delete(void *,unsigned int)&#34; (?? 3 @ YAXPAXI @ Z)在函数中引用   &#34; public:void * __thiscall Vector ::`标量删除   析构函数&#39;(unsigned int)&#34; (?? _ G'$矢量@ @@ķ@ QAEPAXI Z)

案例2中的错误:(在这种情况下,将鼠标悬停在Fin()中的删除操作符上向我显示它是我的重载删除操作符&#34; void operator delete(void * p)&#34; (VS2017))。

  

错误LNK2019未解析的外部符号&#34; void __cdecl运算符   delete(void *,unsigned int)&#34; (?? 3 @ YAXPAXI @ Z)在函数中引用   &#34;长__stdcall Fin(无效)&#34; (?翅片@@ YGJXZ)

在这两种情况下,似乎链接器只查找相同的删除操作符,只是从不同的地方引用了删除操作符。

通过更改我的删除操作符签名

问题已解决

void __cdecl operator delete(void*)

void __cdecl operator delete(void*, unsigned int)

编译器识别我的删除操作符。

我的问题:

  1. 为什么在案例1中链接器在Vector中搜索了delete运算符?我可以理解它试图调用Vector析构函数的编译器的混淆 - 但我想解释一下。

  2. 为什么在案例2中,当我将鼠标悬停在Fin()中的删除操作符上时,它显示&#34; operator delete(void *)&#34;但错误显示&#34;运算符delete(void *,unsigned int)&#34;? (我知道它可能是VS2017错误,但它可能是别的吗?)

  3. 为什么在这两种情况下,我只传递一个参数来删除,但它标识了&#34;运算符delete(void *,unsigned int)&#34;好像我发送了两个参数,而不是&#34; operator delete(void *)&#34;喜欢它吗?

0 个答案:

没有答案