我用过
Pavel Yosifovich's article
使用c++开发windows内核驱动程序(不是出于特殊原因,只是为了研究它)。
在他的文章中,Pavel展示了如何重载new和delete操作符以及如何实现vector。
当我试图用重载的delete运算符编译驱动程序时,由于链接器错误(LNK2019)而失败,这是因为编译器没有编译正确的delete运算符。
我的代码:
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;
}
有两种情况会导致不同的链接器错误消息:
void运算符delete(void*,unsigned int)
(VS2017年)。
错误LNK2019未解析的外部符号“void”cdecl运算符
“public:void*\u此调用向量::`标量删除
析构函数'(unsigned int)'(??_G?$Vector@K@@QAEPAXI@Z)
案例2中的错误:(在本例中,将鼠标悬停在Fin()中的delete运算符上,表明它是我的重载delete运算符
“void运算符删除(void*p)”
(VS2017年)。
删除(void*,unsigned int)“(??函数中引用了3@YAXPAXI@Z)
“长鳍(空)”(?财务@@YGJXZ)
在这两种情况下,链接器似乎都在查找同一个delete运算符,只是delete运算符是从不同的位置引用的。
通过更改删除操作员的签名:
从
void __cdecl operator delete(void*)
到
void __cdecl operator delete(void*, unsigned int)
编译器识别我的delete运算符。
-
为什么在案例1中,链接器搜索向量中的delete运算符?我可以理解编译器试图调用向量析构函数时的混乱,但我想要一个解释。
-
为什么在案例2中,当我将鼠标悬停在Fin()中的delete运算符上时,它显示“operator delete(void*)”,而错误显示“operator delete(void*,unsigned int)”?(我知道这可能是VS2017错误,但这可能是其他原因吗?)
-