7

こんにちは、新規/削除をグローバルにオーバーライドしたライブラリを使用しています。しかし、このライブラリには問題があります。問題は、メイン関数で手動で初期化する必要があることです。

main が呼び出される前にいくつかの関数を初期化する別のライブラリを使用しようとしていますが、残念ながらこのライブラリはこれらの関数内で new を使用しています。オーバーライドされた new/delete キーワードを使用するメモリ マネージャーがまだ初期化されていないため、エラーが発生します。

このライブラリに単体テストを追加したいので、デフォルトのメモリ マネージャーを使用したいと思っています。テストしたいライブラリで使用されているメモリを単体テスト ライブラリでも使用するのはあまり意味がありません。

だから私の質問は、2番目のライブラリを含めるときにグローバルにオーバーライドされた新規/削除を無視して、デフォルトの新規/削除を使用できるかどうかです?

標準の C++ コンパイラを使用して、Windows 7 で Visual Studio 2010 を使用しています。

4

3 に答える 3

1

ライブラリ自体を変更せずにこれが可能だとは思いません。私はそれが静的ライブラリに関するものだと思います(dll内では、オーバーライドされた新規/削除は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

14286objファイルを「識別」します。各シンボルがどこにあるかを確認するには、次のコマンドを実行します。

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

そして、新規/削除を探します。members.txt各シンボルのマングルされた名前と、このシンボルが含まれるobjの識別子が含まれます。例えば

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

14286、シンボルが存在するobj'識別子'を示しています。新規/削除の検索で問題が発生した場合は、次を実行できます。

 DUMPBIN /SYMBOLS input.lib > sym.txt

sym.txtこれは、各シンボルのマングルされた名前とマングルされていない名前にフラッシュされます。

最後に、LIB上記のコマンドでobjファイルを削除します。この例では、をに置き換えobj_to_removecompilation.dir\objfile1.obj、に対してリンクしremoved.libます。

運が悪ければ、必要な他のシンボルがnew/deleteと同じオブジェクトファイルにある可能性があります。その場合、次のようなものを使用してlibを「ハック」できますたとえば、名前newをtodewdeletetoに変更しneleteます)。

于 2012-10-25T21:41:15.743 に答える
0

オーバーライドがマクロで行われる場合は、次を使用できます

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

それが実際に関数オーバーライドによって行われる場合は、標準関数を呼び出すだけの別の場所に配置された別の名前の関数を呼び出す「新しい」マクロを自分で一時的に作成できます。マクロは、関数呼び出しの前に解決されます。

于 2012-09-21T22:09:42.983 に答える
0

メモリ マネージャーの初期化をメインから共有ライブラリに配置できますか?

これが可能な場合は、ライブラリの初期化順序を (依存関係によって) 強制的に実行して、他のものをロードする前にメモリ マネージャーをロード (および初期化) するようにしてください。ただし、共有ライブラリが初期化される順序を強制するためのプラットフォーム固有の回避策に依存するため、これは非常に脆弱な (または特定の) ソリューションです。

于 2012-09-21T13:17:02.483 に答える