1

LoadLibrary()を使用して動的にロードする必要があり、__cdecl呼び出し規約を使用するサードパーティのDLLがあります。VB6のdllを使用できるようにする必要があるため、__ stdcall呼び出し規約を使用し、必要な関数をエクスポートする独自のラッパーDLLを作成しました。

追加の要件が到着し、管理方法を見つけるのに苦労しています。ラップされたDLLは別のアプリケーションにAPIを提供し、アプリケーションの2つのインスタンスに同時に接続する必要があります。DLLにはセッションの概念がないため、これは問題です。一般的な対話では、次のようになります。

tpc_connect("service1")
// Do some stuff
tpc_disconnect()

そして私ができる必要があるのは

session1 = tpc_connect("service1")
session2 = tpc_connect("service2")
// Do some stuff with session1
// Do some stuff with session2
tpc_disconnect(session1)
tpc_disconnect(session2)

私が見ている主な問題は、単一のプロセスを1つのサービスにしか接続できないことです。そのため、最初に試した解決策は、ATLを使用してアウトオブプロセスCOMサーバーを作成することにより、DLLラッパーを別のプロセスに移動することでした。私が今抱えている問題は、COMサーバーのインスタンスを1つしか取得できないことです。

それで、私の質問は(最後に)ATL COMサーバーの新しいインスタンスを強制的に作成する方法はありますか?これは問題への最善のアプローチですか、それとも誰かがこれに取り組むためのより良い方法を考えることができますか?

ありがとうジャクソン

4

2 に答える 2

5

COM サーバーのアイデアを破棄して、元の DLL のコピーを使用することをお勧めします。私はこのアプローチを使用して、スレッドセーフではなく、複数のインスタンスをサポートしていないライブラリの複数のインスタンスを取得しました。

ファイルが異なるため、Windows はそれらすべてを別々のアドレス空間にロードし、分離したままにします。

これは私がしたことです:

  • ライブラリのインスタンスを作成および破棄する関数をラッパーに追加します。

  • 他のすべての関数を変更して、使用しているライブラリのインスタンスへのポインタを取得します。

  • インスタンスの作成関数では、最初にランダムなファイル名を使用して元の DLL へのハード リンクを作成しようとします (つまり、CreateHardLinkを使用します)。それが失敗した場合は、ランダムな名前を使用して DLL の真のコピーを作成します。必要ない場合は、DLL 拡張機能を使用する必要はありません。DLL と関数ポインターのコピーを動的に読み込み、内部構造へのポインターを返します。

  • destroy 関数では、DLL をアンロードして削除するだけです。

  • Vista 以降で一時ディレクトリから DLL をロードする際に制限があるかどうかはわかりませんが、一時ディレクトリにコピーを作成して、クラッシュが発生した場合に削除できることを明確にすることをお勧めします。

これはすべて私にとって完璧に機能します。

于 2009-04-23T13:12:30.613 に答える
1

2 つのセッションだけが必要な場合は、元の dll のコピーを作成して別の名前を付けることができます。ラッパー dll では、2 つの個別の呼び出し (DLL ごとに 1 つ) をエクスポートします。したがって、次のようになります。

session1 = tcp_connect("whatever")      'this points to dll1.dll
session2 = tcp_connect2("whatever")     'this points to a copy of dll1 called dll2.dll

これは、他のアプリケーションの仕様によっては機能する場合があります。とにかく一見の価値があります。

-ドン

于 2009-04-23T12:17:33.477 に答える