7

嗨,我正在使用一个全局覆盖新/删除的库。但是我对这个库有一个问题,问题是它必须在主函数中手动初始化。

现在我正在尝试使用另一个在调用 main 之前初始化一些函数的库,不幸的是这个库在这些函数中使用了 new 。所以我收到错误,因为使用覆盖的 new/delete 关键字的内存管理器尚未初始化。

我真的很想使用默认的内存管理器,因为我想向这个库添加单元测试。使用我要测试的库也被我的单元测试库使用的内存没有多大意义。

所以我的问题是,是否可以在包含第二个库时忽略全局覆盖的 new/delete 并只使用默认的 new/delete?

我在 Windows 7 上使用带有标准 C++ 编译器的 Visual Studio 2010。

4

3 回答 3

1

如果不修改库本身,我认为这是不可能的。我猜它是关于一个静态库(在 dll 中,被覆盖的 new/delete 将由 dll 中的函数指向。)

您可以使用以下命令(可视命令提示符)从静态库中删除 obj 文件:

  LIB /REMOVE:obj_to_remove /OUT:removed.lib input.lib

要找出要删除的 obj,首先运行:

  DUMPBIN /ARCHIVEMEMBERS input.lib

您将看到诸如

    Archive member name at 14286: /0  compilation.dir\objfile1.obj

14286'标识' obj 文件。要查看每个符号的位置,请运行:

 DUMPBIN /LINKERMEMBER:1 input.lib > members.txt

并寻找新的/删除。members.txtwill 包含每个符号的错位名称和该符号所在的 obj 的标识符。例如

    14286 ?_Rank@?$_Arithmetic_traits@C@std@@2HB

14286告诉你符号所在的 obj '标识符' 。如果您在查找新/删除时遇到问题,可以运行:

 DUMPBIN /SYMBOLS input.lib > sym.txt

它将刷新到sym.txt每个符号的损坏和未损坏名称中。

最后,使用上面的命令删除 obj 文件,在我们的示例中LIB替换obj_to_removecompilation.dir\objfile1.obj,并链接到removed.lib.

现在,如果您不走运,您需要的其他符号可能与 new/delete 位于同一目标文件中。在这种情况下,您可以使用类似这样的方式“破解”库例如重命名newdew和。)deletenelete

于 2012-10-25T21:41:15.743 回答
0

您可以将内存管理器的初始化从 main 放到共享库中吗?

如果这是可能的,您可以尝试强制库的初始化顺序(通过依赖项)在加载其他任何内容之前加载(并初始化)内存管理器。然而,这是一个非常脆弱(或特定)的解决方案,因为它将依赖于平台特定的解决方法来强制共享库的初始化顺序。

于 2012-09-21T13:17:02.483 回答
0

如果使用宏完成覆盖,您可以使用

#pragma push_macro ("new")
#undef new
...code with standard new here ...
#pragma pop_macro ("new")

如果它真的是通过函数覆盖完成的,那么您可以自己临时构建一个“新”宏,它调用一个具有另一个名称的函数,该函数位于其他地方,它只调用标准函数。宏在函数调用之前被解析。

于 2012-09-21T22:09:42.983 回答