操作符new已在带有库的自定义内存管理器中定义

operator new already defined in custom memory manager with library

本文关键字:内存 自定义 管理器 定义 new 操作符      更新时间:2023-10-16

不好意思,但希望描述能让你更清楚。

目前我有一个主要的应用程序是与其他库(如libpng, libvorbis等)一起构建的。我试图将libtheoraplayer添加到主应用程序,但我一直遇到问题:

1)链接到一个预先构建的llibtheoraplayer库并包括适当的头文件给我一个错误,说不能找到pushMemoryManager(我们自定义内存管理器的一部分)

2)与主应用程序一起构建库会导致链接错误"error LNK2005: "void * __cdecl operator new(unsigned int,void *)"(??2@YAPAXIPAX@Z)已经定义在win32Mem.obj"

我不太确定从哪里开始调试这个。主应用程序不支持STL,我开始将libtheoraplayer中对STL的引用更改为我们自己的STL替代品,但在找到违规文件并更改它们后,我仍然得到如上的错误2。

有什么疯狂的想法吗?

/FORCE的链接器错误(转换为警告)静音,并祈祷没有跨库分配最终使用不同的分配器。

在Windows (NT或CE)上替换分配函数相当困难,因为:

  1. 动态符号是从特定的库中加载的,因此您将替换代码中使用的分配器,而不是替换动态链接库中使用的分配器。如果你不动态链接并使用/FORCE沉默链接器错误,它会做正确的事情并覆盖标准库中的分配器。

    使用动态链接时,如果一个库中的代码被分配,而另一个库中的代码被释放,那么所使用的分配器将不匹配,从而可能崩溃。不幸的是,即使两个函数都由同一个库定义,但其中一个是模板(因此实例存在于引用它的库中)而另一个不是模板(因此它存在于定义它的库中),也很容易发生这种情况。

  2. 它们有一些非标准的分配器入口点,有时从其他代码中使用它们。我们曾经使用duma库,并且实际上设法覆盖C (malloc/realloc/free)和c++ (operator new和operator delete)分配器,但是当我们开始使用iostreams时遇到了瓶颈,它们使用标准函数分配,但使用__debug_free之类的东西或其他方式分配。

顺便说一下,这在Linux上是绝对微不足道的,因为在GNU libc malloc中,realloc和free通过指针调用真正的分配器,你可以很容易地覆盖(operator new和operator delete基本上在任何地方分别调用malloc和free)。