/*
1つ以上のダイナミックリンクライブラリ(DLL)をアドレス空間にロードするWindowsプロセスでは、そのアドレス空間をすべてのロード済み領域DLL - これらのDLLはプロセスのアドレス空間内の任意のメモリに読み書きできます。ただし、オブジェクトがヒープ上に割り当てられると、各モジュール(プロセスのロードされたDLLのうちの1つである.exe
)は、独自のヒープから割り当てられます。このため、割り振りを実行した同じヒープに対してメモリーを割り振り解除することが重要です。すべては私には理にかなっていると私は私が整理物事を保つためにstd::unique_ptr
を使用するかもしれないと思ったことWindows DLLモジュールの境界を越えてヒープ割り当てリソースをクリーンアップする問題
。これは私が使ったアプローチです。 (私は現時点では私のコンパイラが手元にありませんが、私はこれらのスニペット/擬似コードは、私の意図を伝えるのに十分明らかになると思う。
*/
Library.hは
class ILibrary
{
public:
virtual void DoStuff() = 0;
};
struct Deleter
{
void operator()(ILibrary *p)
{
delete p;
}
};
typedef std::unique_ptr<ILibrary, Deleter> Ptr;
//*MyLibrary.dll*
//Includes Library.h
//Exports:
void GetMyLibrary(Ptr & library)
{
library = Ptr(new MyLibrary); // point (1)
}
//**Program.exe**
//Includes Library.h
//Imports MyLibrary.dll (GetMyLibrary export)
int main()
{
Ptr local;
MyLibrary->GetMyLibrary(local);
local->DoStuff();
} // heap corruption on cleanup
あなたは私は私のライブラリへのポインタを保持する変数local
を作成します。私のライブラリとメインプログラムの両方が同じヘッダLibrary.hを使用することがわかります。(DLL内で呼び出さ)GetMyLibrary方法私は渡された基準にnew unique_ptr
を割り当て、割り当て私は「Deleted」を「ポイント1」で使用した私のメインプログラムの変数local
に最初に割り当てられたDeleterではなく、クリーンアップに使用されるDLLのext。意味、地元がスコープ外になったとき、私はDELETERは、DLLのコンテキストから呼び出すことがしたいので、DLLのDELETERをトリガーするためにそのクリーンアップではなく、最初はそれに割り当てられた1(すなわち、私はlibrary = Ptr(new MyLibrary)
代わりのlibrary.reset(new MyLibrary)
を使用したいです)
とにかく、プログラムは、除外中、ローカルunique_ptr
が破壊されたとき以外は、ヒープ破損例外(デバッグ時)が表示され、間違ったヒープを削除していると考えられます。 unique_ptr
は私が期待どおりに動作していません)
最終的に、私は問題を解決しました。これははるかにクリーンなようですが、なぜ上記のアプローチが失敗したのか不思議でした。
「** **ヒープ」 - それはあなたの問題の大部分です。限りのWindowsに関しては、** **ヒープは[ 'GetProcessHeap'](https://msdn.microsoft.com/en-us/library/windows/desktop/aa366569(V = VS.85)によって返されます.aspx)と、そのヒープ_is_はEXEとDLLの間で共有されます(したがって、 "プロセスヒープ"という名前)。 – MSalters
リンクをありがとう、私はそれを読み上げるでしょう。 – charunnera