2011-02-17 17 views
4

シングルスレッド環境で使用するために設計された古いC++ライブラリを使用しています。マルチスレッド環境で旧シングルスレッドC++ライブラリを使用する方法

ライブラリは、ライブラリの内部データ構造を変更する初期化用のインターフェイスと、データの読み取りと計算のみを行う使用法を公開します。

私の目的は、Windowsマルチスレッドアプリケーションで、異なるデータで初期化されたdllのインスタンスを呼び出す異なるスレッドを使用することです。

マルチスレッドを可能にするためにdllを書き直すことは禁止されていると仮定すると、DLLの複数のインスタンスを別々のメモリ空間を持つ同じプロセスに存在させる方法がありますか?

+0

興味深い別のアイデアは、異なるAppDomainsを使用して、ライブラリの各インスタンスを1つ作成し、その中にロードすることです.AppDomainsは別々のメモリスペースを提供し、アンロードすることができ、内のアセンブリ。 –

答えて

6

DLLに静的リソースが含まれている場合、それらは作成されたすべてのインスタンスで共有されます。

可能な方法の1つは、単一のインスタンスを作成し、何らかの種類のロック機構を使用してそのインスタンスへのアクセスを制限することです。これにより、使用状況に応じてパフォーマンスが低下する可能性がありますが、DLLの内部構造を変更することなく、複数のインスタンスで作業するのは難しい場合があります。

+5

私は一般的な考え方に同意しますが、dllがスレッドローカルストレージを使用している場合でも問題が発生する可能性があることに注意してください。シングルスレッド化されているので、TLS *を目的に使用しませんが、依存関係を介して間接的に使用している可能性があります。したがって、あるスレッドから設定した場合、別のスレッドからの呼び出しが機能しないことがあります。ラップの次のレベルは単なるロックではなく、このdllを管理することを目的とするスレッドを作成し、このスレッドにメッセージを送信して応答を待つことによってすべてのdllの関数にアクセスします。 –

+0

@Steve Jessop:これは私の最初のアイディアでしたが、この場合、一度に1セットのデータでdllを初期化することができました。理想的なソリューションは、同時に各スレッドに対して異なる初期化パラメータを持つことができます。 –

+2

@Coffee:ああ、申し訳ありませんが、私は正しくdllが複数のスレッドをサポートしているだけでなく、事実上ハンドル固有のグローバルデータも持っています。私はあなたがブルートフォースによってDLLをクローンすることができると確信しています - それをリネームして、それだけでLoadLibrary/GetProcAddress経由でアクセスし、リンクではありません。これは、固定数のコピーに対しては本当に良いことですが、実行可能ファイルがdllの新しい名前をその場で選択してもらいたいとは思っていません。マシンがロックダウンされていない限り、明らかにハッキーになるかもしれません。 –

5

プロセス内の1つのDLLに接続されているすべてのスレッド間で静的リソースを共有することは、ここで争われます。

しかし、これを達成するためのトリックがあります。 DLLの名前が異なる限り、システムはそれらが異なるとみなし、コードとデータの別々のインスタンスが作成されます。

これを達成する方法は、各スレッドについて、DLLを一時ファイルにコピーし、そこからLoadLibraryでロードすることです。 libファイルではなく明示的なリンク(GetProcAddress)を使用する必要がありますが、それは本当に唯一の方法です。

+2

バリエーションは、同じインターフェイスを公開するラッパーDLLですが、スレッドローカルストレージを使用して各呼び出しをDLLのスレッドごとのコピーに転送します。これは、ラッパーDLLのすべてのトリッキーを分離します。 – MSalters

+0

@Salters cute idea! –

関連する問題