2009-07-10 11 views
1

VorwortProbleme wxWidgets (wxMSW) innerhalb mehrerer DLL-Instanzen

Ich entwickle VST-Plug-in, die DLL-basierten Software-Module geladen und von VST-Unterstützung Host-Anwendungen. Um ein VST-Plugin zu öffnen, laden die Host-Anwendungen die VST-DLL und rufen eine entsprechende Funktion des Plugins auf, während sie ein natives Fenster-Handle bereitstellen, mit dem das Plugin seine GUI zeichnen kann. Ich habe es geschafft, meinen ursprünglichen VSTGUI Code in das wxWidgets-Framework zu portieren und jetzt laufen alle meine Plugins unter wxMSW und wxMac, aber ich habe immer noch Probleme unter wxMSW, um einen korrekten Weg zum Öffnen und Schließen der Plugins zu finden und ich bin nicht sicher, ob dies der Fall ist ein WxMSW-only-Problem

Problem

Wenn ich VST-Host-Anwendung verwenden I und in der Nähe mehrere Instanzen eines meiner VST-Plugins ohne Probleme öffnen können. Sobald ich ein anderes meiner VST-Plugins neben meinem ersten VST-Plugin öffne und dann alle Instanzen meines ersten VST-Plugins schließe, stürzt die Anwendung nach kurzer Zeit innerhalb der wxEventHandlerr :: ProcessEvent Funktion ab und meldet mir das wxTheApp-Objekt ist während der Ausführung von wxTheApp-> FilterEvent nicht mehr gültig (siehe unten). So scheint es, dass die wxTheApp-Objekte nach dem Schließen aller Instanzen des ersten Plugins gelöscht wurden und für das zweite Plugin nicht mehr verfügbar sind.

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 
    } 

    .... 
} 

Voraussetzungen

1.) Alle meine VST-Plugins ein dynamisch gelinkt gegen die C-Runtime und wxWidgets-Bibliotheken. Im Hinblick auf die wxWidgets Forum schien dies der beste Weg, mehrere Instanzen der Software nebeneinander laufen zu lassen.

2.) Die DllMain jede VST-Plugin wie folgt definiert ist:

// 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) 

Frage

Wie kann ich dieses Verhalten bzw. verhindern, wie kann ich das wxTheApp Objekt, wenn ich richtig behandeln haben mehrere Instanzen von verschiedenen VST-Plugins (DLL-Module), die dynamisch gegen die C-Runtime und WxWidgets Bibliotheken verknüpft sind?

Beste reagards, Steffen

+0

Da Sie eine Antwort noch nicht, ich schlage vor, Sie bei kvraudio fragen über, wo es eine Menge von VST-Programmierer. http://www.kvraudio.com/forum/viewforum.php?f=33 – Nosredna

Antwort

0

Wir hatten ähnliche Probleme ein LSP mit wxWidgets erstellt, wenn ein WxWidgets Anwendung unserer DLL geladen. Überprüfen Sie vor dem Aufruf von :: wxInitialize() nach NULL == wxTheApp.

Pseudo-Code:

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

Auch schlage ich vor, so wenig möglich in Ihrer DllMain() wie möglich zu tun, zum Beispiel Verschieben Sie wxInitAllImageHandlers() woanders nach Möglichkeit. Vielleicht möchten Sie auch verfolgen, wenn Sie :: wxInitialize() angerufen haben, um :: wxUninitialize()

0

Ich stieß auf ein ähnliches Problem, aber mit Acrobat-Plugins. Bei der Anpassung unserer Acrobat-Plugins an Acrobat X (10) mussten wir Code entfernen, der sich auf ADM bezieht (Acrobat Dialog Manager - Ein plattformübergreifendes GUI-Framework auf Acrobat 7, 8 & 9. Entfernt mit Acrobat X) und a anderes GUI-Framework.

Acrobat SDK wird mit Beispielen für die Verwendung von wxWidgets als plattformübergreifendes Framework geliefert, so dass wir auf diesem Weg (wir unterstützen MAC & Windows). Die Plugin-Architektur von Acrobat ist der oben beschriebenen sehr ähnlich: dlls (für Acrobat-Plugins ist die Binärdateierweiterung * .api), die von einem Hauptprozess (exe) dynamisch geladen werden und deren Funktionen in einer dokumentierten aufgerufen werden , vordefinierte Reihenfolge.

Da das Acrobat wxWidgets-Beispiel mit 2.8.12 geschrieben wurde und aufgrund der Tatsache, dass dies die stabile Version ist, haben wir uns entschieden, die 2.9.x-Version NICHT zu verwenden.

Also haben wir unsere Plugins (insgesamt 3 verschiedene Plugins) statisch mit den wx2.8.12-Bibliotheken verknüpft und festgestellt, dass, wenn 3 davon installiert sind, die beiden zuletzt geladenen nicht funktionierten. Damit meine ich - unsere benutzerdefinierten wxFrames, wxWindows & wxDialogs, die zu diesen beiden Plugins gehören, waren alle durcheinander (wie jemand versucht hat, sie zu löschen, mit Gummi :-)).

Graben tief wir verengten es auf die Tatsache, dass das erste Plugin geladen wird, initialisiert wxWidgets und letztere nicht, obwohl der explizite Aufruf von wxInitialize(). Irgendwas ist schiefgelaufen ....

Hier habe ich vergessen zu erwähnen - In einem Acrobat Plugin kann man die DllMain() Funktion nicht ändern, daher wird die Initialisierung von wx in einer "Plugin Init() Funktion" gemacht.

Nur um klar zu sein - Die wx-Bibliotheken sind statisch mit den * .api-Dateien verknüpft, so dass jeder eine eigene "Kopie" haben sollte und sich nicht gegenseitig beeinflussen sollte.

Verwendung von Google für 2-3 volle Tage I this Post finden verwaltet, die this Patch anzuwenden vorgeschlagen (für 2.8x NUR !!!). Ich glaube (oder hoffe), dass die Version 2.9.x nicht von diesem Problem betroffen ist (hatte keine Chance, es zu überprüfen).

BTW - Der Patch ist nur eine Datei, die sehr klar ist, so lesen Sie den Code, um es zu verstehen und ruhig zu sein, dass es keinen Schaden tut, ist ziemlich einfach.

Ich hoffe, dass andere mit wx 2.8.x und leiden unter dem gleichen Problem wird dies finden.

Omri