1

序文

DLLベースのソフトウェアモジュールであり、VSTをサポートするホストアプリケーションによってロードされるVSTプラグインを開発しています。VSTプラグインを開くには、ホストアプリケーションがVST-DLLをロードし、プラグインがGUIを描画するために使用できるネイティブウィンドウハンドルを提供しながら、プラグインの適切な関数を呼び出します。元のVSTGUIコードをwxWidgets-Frameworkに移植し、すべてのプラグインをwxMSWとwxMacで実行できるようになりましたが、プラグインを開閉する正しい方法を見つけるためにwxMSWで問題が発生し、これがwxMSWのみの問題。

問題

VSTホストアプリケーションを使用している場合は、VSTプラグインの1つの複数のインスタンスを問題なく開いたり閉じたりできます。最初のVSTプラグイン以外に別のVSTプラグインを開き、最初のVSTプラグインのすべてのインスタンスを閉じるとすぐに、wxEventHandlerr :: ProcessEvent関数内でアプリケーションがクラッシュし、wxTheAppオブジェクトが通知されます。 wxTheApp-> FilterEventの実行中は無効になります(以下を参照)。したがって、最初のプラグインのすべてのインスタンスを閉じた後にwxTheAppオブジェクトが削除され、2番目のプラグインで使用できなくなったようです。

bool wxEvtHandler::ProcessEvent(wxEvent& event)
{
    // allow the application to hook into event processing
    if ( wxTheApp )
    {
        int rc = wxTheApp->FilterEvent(event);
        if ( rc != -1 )
        {
            wxASSERT_MSG( rc == 1 || rc == 0,
                          _T("unexpected wxApp::FilterEvent return value") );

            return rc != 0;
        }
        //else: proceed normally
    }

    ....
}

前提条件

1.)すべてのVSTプラグインは、C-RuntimeおよびwxWidgetsライブラリに対して動的にリンクされています。wxWidgetsフォーラムに関しては、これがソフトウェアの複数のインスタンスを並べて実行するための最良の方法であるように思われました。

2.)各VSTプラグインのDllMainは次のように定義されています。

// WXW
#include "wx/app.h"
#include "wx/defs.h"
#include "wx/gdicmn.h"
#include "wx/image.h"

#ifdef __WXMSW__
#include <windows.h>
#include "wx/msw/winundef.h"

BOOL APIENTRY DllMain
( HANDLE hModule,
  DWORD ul_reason_for_call,
  LPVOID lpReserved )
{
        switch (ul_reason_for_call)
        {
            case DLL_PROCESS_ATTACH:
        {
                  wxInitialize();
                ::wxInitAllImageHandlers();
            break;
        }
            case DLL_THREAD_ATTACH:
                       break;
            case DLL_THREAD_DETACH:
                       break;
            case DLL_PROCESS_DETACH:
                       wxUninitialize();
                           break;
        }

    return TRUE; 
}

#endif // __WXMSW__

class Application : public wxApp {};
IMPLEMENT_APP_NO_MAIN(Application)

質問

C-RuntimeおよびwxWidgetsライブラリに対して動的にリンクされている異なるVSTプラグイン(DLLモジュール)の複数のインスタンスがある場合、この動作をそれぞれ防ぐにはどうすればよいですか?wxTheAppオブジェクトを適切に処理するにはどうすればよいですか?

最高のリーガード、ステフェン

4

2 に答える 2

0

同様の問題が発生しましたが、Acrobat プラグインを使用していました。Acrobat プラグインを Acrobat X (10) に調整する際に、ADM (Acrobat Dialog Manager - Acrobat 7、8、および 9 ではクロスプラットフォームの GUI フレームワークでした。Acrobat X で削除) に関連するコードを削除し、別のプラグインを使用する必要がありました。 GUI フレームワーク。

Acrobat SDK には、クロスプラットフォーム フレームワークとして wxWidgets を使用するサンプルが付属しているため、その方向に進みました (MAC と Windows をサポートしています)。Acrobat のプラグイン アーキテクチャは、上記で説明したものと非常によく似ています: dll (Acrobat プラグインの場合、バイナリ ファイル拡張子は *.api) は、メイン プロセス (exe) によって動的にロードされ、それらの関数はドキュメントで呼び出されます。事前定義された順序。

Acrobat wxWidgets の例は 2.8.12 で書かれており、これが安定したバージョンであるため、2.9.x の進行中のバージョンを使用しないことにしました。

そのため、プラグイン (合計 3 つの異なるプラグイン) を wx2.8.12 ライブラリに静的にリンクしたところ、そのうちの 3 つがインストールされている場合、最後にロードされた 2 つが機能していないことがわかりました。つまり、これら 2 つのプラグインに属するカスタム wxFrames、wxWindows & wxDialogs はすべてめちゃくちゃでした (誰かがそれらをゴムで消そうとしたように :-))。

深く掘り下げて、wxInitialize() への明示的な呼び出しにもかかわらず、最初のプラグインがロードされて wxWidgets を初期化し、後者はそうしないという事実に絞り込みました。何かがうまくいかなかった....

ここで言い忘れましたが、Acrobat プラグインでは DllMain() 関数を変更できないため、wx の初期化は「Plugin Init() 関数」で行われます。

明確にするために-wxライブラリは* .apiファイルに静的にリンクされているため、それぞれに独自の「コピー」が必要であり、互いに影響を与えないようにする必要があります。

Google を丸 2 ~ 3 日間使用した結果、このパッチを適用することを提案するこの投稿を見つけることができました(2.8x のみ!!!)。2.9.x バージョンではこの問題が発生しないと信じています (または希望します) (確認する機会がありませんでした)。

ところで-パッチは非常に明確な1つのファイルにすぎないため、コードを読んで理解し、害がないことを落ち着かせるのは非常に簡単です。

wx 2.8.x を使用していて、同じ問題に苦しんでいる他の人がこれを見つけてくれることを願っています。

オムリ

于 2011-08-29T17:23:13.197 に答える
0

wxWidgets アプリケーションが DLL をロードしたときに、wxWidgets で作成された LSP を使用すると、同様の問題が発生しました。::wxInitialize() を呼び出す前に、NULL == wxTheApp であることを確認してください。

擬似コード:

BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
    switch(dwReason) {
        case DLL_PROCESS_ATTACH :
            if(NULL == wxTheApp) {
                ::wxInitialize();
            }
            break;
    }
}

また、DllMain() で可能な限り何もしないことをお勧めします。たとえば、可能であれば wxInitAllImageHandlers() を別の場所に移動します。さらに、::wxInitialize() を呼び出して ::wxUninitialize() とペアリングしたかどうかを追跡したい場合があります。

于 2009-08-26T22:31:32.433 に答える