IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

wxWidgets Discussion :

Exporter des widgets depuis une DLL


Sujet :

wxWidgets

  1. #1
    Membre habitué

    Inscrit en
    Mars 2002
    Messages
    83
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 83
    Points : 125
    Points
    125
    Par défaut Exporter des widgets depuis une DLL
    Bonjour.

    Après moult recherche, je n'ai pas pu trouver la solution au problème suivant.
    Je voudrais déporter la création de fenêtre fille dans des DLL. Dan sun premier temps je crée un dll que je link en statique et qui exporte une classe créant un un Frame et un wxPanel fils. Ca marche super bien.
    Là ou ça coince, c'est quand je créer un thread avec wxThread. Je ne sais pas pourquoi (mais je pense que cela vient du passage de l'instance d'execution entre l'exe et la DLL) mais ça plante. Je peux soit utiliser un wxThread dans l'exe, soit exporter des Widgets depuis la dll, mais pas les deux. La création de la fenêtre, et du thread se passe bien, mais dés que le système le dispatcheur de message de la fenêtre tourne en même temps que le thread l'application plante.


    le code :

    The DLL LibTest :
    LibTest.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    #ifndef __LIB_EXPORT__
    #define __LIB_EXPORT__
     
    #ifdef LIB_EXPORTS
    	#define LIB_API __declspec(dllexport)
    #else
    	#define LIB_API __declspec(dllimport)
    #endif
     
    extern HINSTANCE hModuleInst;
     
    class wxDLLApp : public wxApp
    {
            bool OnInit();
            DECLARE_EVENT_TABLE()
    };
     
    class LIB_API LibExport
    {
    	public:
    		LibExport( );
    		virtual ~LibExport( );
     
    		wxFrame * CreateParent( );
    		wxWindow * CreateChild( wxWindow * wxParent);
     
    	public :
    		wxWindow * m_pWndParent;
    };
     
    #endif //__LIB_EXPORT__
    LibTest.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    #include "wx/wxprec.h"
     
    #ifndef WX_PRECOMP
        #include "wx/wx.h"
    #endif
     
    #include "wx/app.h"
    #include <windows.h>
    #include "LibExport.h"
     
    HINSTANCE hModuleInst = NULL;
     
    BEGIN_EVENT_TABLE(wxDLLApp, wxApp)
    END_EVENT_TABLE()
     
    IMPLEMENT_APP_NO_MAIN(wxDLLApp)
     
    BOOL APIENTRY DllMain( HANDLE hModule, 
                           DWORD  ul_reason_for_call, 
                           LPVOID lpReserved
    					 )
    {
        switch (ul_reason_for_call)
    	{
    		case DLL_PROCESS_ATTACH:
    		{
    			hModuleInst = (HINSTANCE)hModule;
     
    			wxSetInstance( hModuleInst);
                int argc = 0;
                char **argv = NULL;
                wxEntryStart(argc, argv);
                if ( !wxTheApp || !wxTheApp->CallOnInit() )
                        return FALSE;
    		}
    		break;
     
    		case DLL_THREAD_ATTACH:
    		case DLL_THREAD_DETACH:
    		case DLL_PROCESS_DETACH:
    			wxEntryCleanup( );
    			break;
        }
     
        return TRUE;
    }
     
    bool wxDLLApp::OnInit()
    {
            return true;
    }
     
    LibExport::LibExport( )
    {
    	m_pWndParent = NULL;
    }
     
    LibExport::~LibExport( )
    {
    }
     
    wxFrame * LibExport::CreateParent( )
    {
        return new wxFrame( NULL, wxID_ANY, _T(""), wxPoint(0, 0), wxDefaultSize);
    }
     
    wxWindow * LibExport::CreateChild( wxWindow * wxParent)
    {
    	wxSetInstance( hModuleInst);
     
    	wxPanel * pPane = new wxPanel( wxParent, 10000, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER|wxTAB_TRAVERSAL );
    	if( pPane != NULL)
    	{
    		wxGridSizer* itemGridSizer16 = new wxGridSizer(1, 1, 0, 0);
    		pPane->SetSizer(itemGridSizer16);
     
    		wxStaticText* itemStaticText17 = new wxStaticText( pPane, wxID_STATIC, _("Static text"), wxDefaultPosition, wxDefaultSize, 0 );
    		itemGridSizer16->Add(itemStaticText17, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
    	}
     
    	return pPane;
    }
    Now the application:
    DocView.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #ifndef __DOCVIEWSAMPLEH__
    #define __DOCVIEWSAMPLEH__
     
    class ManagerThread : public wxThread
    {
    	public:
    		ManagerThread( void);
    		~ManagerThread( );
     
    		virtual void * Entry( );
     
    	public:
    		bool m_isAlive;
    };
     
     
    class MyApp: public wxApp
    {
    	public:
    		MyApp(void);
    		bool OnInit(void);
    		int OnExit(void);
     
    		ManagerThread * pWorker;
    };
     
    DECLARE_APP(MyApp)
    #endif
    Docview.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    #include "wx/wxprec.h"
     
    #ifndef WX_PRECOMP
    #include "wx/wx.h"
    #endif
     
    #include "docview.h"
    #include "LibExport.h"
     
    IMPLEMENT_APP(MyApp)
     
    MyApp::MyApp(void)
    {
    }
     
    bool MyApp::OnInit(void)
    {
    	LibExport lib;
     
    	//wxFrame * pFrame = (wxFrame *)lib.CreateParent( );
    	wxFrame * pFrame = new wxFrame( NULL, wxID_ANY, _T(""), wxPoint(0, 0), wxDefaultSize);
     
    	if( pFrame != NULL)
    	{
    		wxPanel * pane = (wxPanel *)lib.CreateChild( (wxWindow *)pFrame);
     
    		pFrame->Maximize( true);
    		pFrame->Show( true);
    		SetTopWindow( pFrame);
     
    		pWorker = new ManagerThread( );
    		if( pWorker->Create() == wxTHREAD_NO_ERROR )	
    			pWorker->Run( );
     
    		return true;
    	}
    	else
    	    return false;
    }
     
    int MyApp::OnExit(void)
    {
    	if( pWorker)
    		delete pWorker;
     
        return 0;
    }
     
     
    ManagerThread::ManagerThread( void )
    			: wxThread()
    {
    	m_isAlive = false;
    }
     
    ManagerThread::~ManagerThread( )
    {
    	m_isAlive = false;
    }
     
    void * ManagerThread::Entry( )
    {
    	m_isAlive = true;
     
    	while( m_isAlive)
    	{
    		wxThread::Sleep(100);
    	};
     
    	return NULL;
    }

    merci beaucoup de votre attention.

  2. #2
    Membre éclairé Avatar de hansaplast
    Homme Profil pro
    Artisant logiciel
    Inscrit en
    Septembre 2005
    Messages
    949
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Artisant logiciel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 949
    Points : 730
    Points
    730
    Par défaut
    jz veut pas dire de betise, donc attend l'avis d'un autre avant de me prendre au pie de la lettre, amis, je croit qu'un thread partage la meme zone memoire que l'executable.

    donc, peut etre qu'en le mettant dnas une DLL ca n'es tpas possible?

    a moi de faire une DLL dynamique, ou je ne sait pas quel autre truc vaudou...

    voila, un bout de pseudo reponse, en attendant une de pro...

  3. #3
    Membre habitué

    Inscrit en
    Mars 2002
    Messages
    83
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 83
    Points : 125
    Points
    125
    Par défaut
    Merci.

    Pour la mémoire : Oui. Mais sous windows. Un thread est attaché à l'instance qu'il le créer (EXE ou DLL).

    Mais dans mon cas : Il y a un thread principal dans l'exe qui gère des évènements matériels (port série, carte d'acquisition, ...) Chaque matériel possède un dll, pour le traitement, les fenêtre de paramètrage, ... Enfin pour que je ne soit pas obliger de tout recompiler à chaque fois. Donc non le thread principal ne peut être placé dans l'une des dll.

    Je sais que je ne suis pas loin, avec les MFC de krosoft, j'avais eu le même soucis, et pour y palier il falait utiliser les fonctions du genre "AfxSetResourceHandle "

  4. #4
    Membre éclairé Avatar de hansaplast
    Homme Profil pro
    Artisant logiciel
    Inscrit en
    Septembre 2005
    Messages
    949
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Artisant logiciel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 949
    Points : 730
    Points
    730
    Par défaut
    je vient de lire brievement ton code, je voit 2 trucs :

    - pWorker n'est pas declaré

    - m_isAlive est accédé par le thread et par des methodes, sans utiliser de mutex ou autre.

  5. #5
    Membre habitué

    Inscrit en
    Mars 2002
    Messages
    83
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 83
    Points : 125
    Points
    125
    Par défaut
    Meric pour le temps passer à lire mes âneries.

    Citation Envoyé par hansaplast
    je vient de lire brievement ton code, je voit 2 trucs :

    - pWorker n'est pas declaré
    Peut être trop brièvement parceque pWorker est définie dans le fichier docview.h . C'est une propriétés de la classe MyApp.

    Citation Envoyé par hansaplast
    - m_isAlive est accédé par le thread et par des methodes, sans utiliser de mutex ou autre.
    C'est normal. Il sagit ici d'un projet fait vite fait pour montrer le problème mais la synchro n'importe pas.

    Sinon pour la solution :
    Le probleme est que j'ai oublier quelques breaks dans la fonction dllMain. Ce qui fait que le programme appel "wxEntryCleanup( );" lors de l'attachement de la dll au thread principal.

    donc il faut faire :

    case DLL_THREAD_ATTACH:
    break;
    case DLL_THREAD_DETACH:
    break;
    case DLL_PROCESS_DETACH:
    wxEntryCleanup( );
    break;
    Autre chose très importante : Il est nécessaire d'utiliser l'implémentation d'un objet wxApp (voir le code utiliser avec la classe wxDLLApp) Car sans cela le classname ne sera pas enregister avec la fonction "RegisterClassEx".

    En tout cas ce petit problème poura faire partie de la FAQ. parceque la literature n'est pas tres prolyxe sur wxWidgets et les dll.

  6. #6
    Membre éclairé Avatar de hansaplast
    Homme Profil pro
    Artisant logiciel
    Inscrit en
    Septembre 2005
    Messages
    949
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Artisant logiciel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 949
    Points : 730
    Points
    730
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    case DLL_THREAD_ATTACH:
    break;
    case DLL_THREAD_DETACH:
    break;
    case DLL_PROCESS_DETACH:
    wxEntryCleanup( );
    break;
    pourquoi ne pas faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    case DLL_PROCESS_DETACH:
    wxEntryCleanup( );
    break;
    etant donné que tu ne gere pas les autres etats?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 8
    Dernier message: 01/02/2013, 14h39
  2. Réponses: 1
    Dernier message: 06/10/2009, 19h56
  3. Exporter et utiliser une classe depuis une DLL
    Par Havy_25 dans le forum Langage
    Réponses: 1
    Dernier message: 14/07/2009, 19h31
  4. Exportation de données depuis une base
    Par david71 dans le forum JBuilder
    Réponses: 2
    Dernier message: 22/06/2004, 10h31
  5. Gestion des Utilisateurs depuis une application
    Par LLaurent dans le forum XMLRAD
    Réponses: 4
    Dernier message: 25/03/2003, 16h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo