我使用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中链接器在Vector中搜索了delete运算符?我可以理解它试图调用Vector析构函数的编译器的混淆 - 但我想解释一下。
为什么在案例2中,当我将鼠标悬停在Fin()中的删除操作符上时,它显示&#34; operator delete(void *)&#34;但错误显示&#34;运算符delete(void *,unsigned int)&#34;? (我知道它可能是VS2017错误,但它可能是别的吗?)
为什么在这两种情况下,我只传递一个参数来删除,但它标识了&#34;运算符delete(void *,unsigned int)&#34;好像我发送了两个参数,而不是&#34; operator delete(void *)&#34;喜欢它吗?