Merci bien, tout est okEnvoyé par Laurent Gomila
Merci bien, tout est okEnvoyé par Laurent Gomila
JE reviens de nouveau avec une question sur un warning
Celui intervient dans la compilation du .h de ma dll sur la déclaration de variable de classe private de type string ou bitset (je ne sais pas pour les autres types).
J'ai regardé l'erreur dans l'aide : il faut rajouter __declspec(dllexport) mais je ne vois pas où...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 ...dll_paq_ts.h(39) : warning C4251: 'Paquet::HEADER_continuity_counter' : class 'std::bitset<_Bits>' nécessite une interface DLL pour être utilisé(e) par les clients de class 'Paquet' with [ _Bits=4 ]
Voici la partie de mon code qui créé des warning :
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 ... class IMPEXP Paquet { public: Paquet(); // Constructeur par défaut ~Paquet(); ... private: string contenu; //A partir d'ici, un warning par ligne bitset<8> HEADER_syncbyte; bitset<1> HEADER_transport_error_indicator; bitset<1> HEADER_start_indicator; bitset<1> HEADER_transport_priority; bitset<13> HEADER_PID; bitset<2> HEADER_scrambling_control; bitset<2> HEADER_adaptation_field_control; bitset<4> HEADER_continuity_counter; };
Tu peux, au choix :
- Ignorer cet avertissement (ça fonctionnera dans des conditions normales)
- Exporter toutes les instanciations de std::bitset que tu utilises
La syntaxe devrait être du genre :
- Ne pas faire apparaître de classe non exportée dans l'interface de tes classes exportées (c'est pas toujours pratique...)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 template <> IMPEXP std::bitset<1>; template <> IMPEXP std::bitset<2>; ...
Merci encore Laurent, je vais ignorer si ca n'a pas d'incidence.
J'ai ENCORE un soucis J'essaie de faire pas mal de truc et de m'exercer à manipuler des dll donc c'est normal que je rencontre des problèmes. Voici celui auquel je suis confronté.
J'ai 2 DLL : DLL1 et DLL2.
Dans une classe de ma DLL1, je déclare un public bool "arret_des_threads". Ce public bool sera amené à être modifié par une méthode de ma DLL2.
J'ai fait mes déclaration de DLL1 dans DLL2 bien comme il faut mais j'ai une erreur à la compile sur cette variable:Dans le .h de ma DLL1, ce public bool est déclaré de cette facon:
Code : Sélectionner tout - Visualiser dans une fenêtre à part dll_file_output error LNK2001: symbole externe non résolu "public: static bool mux::arret_des_threads" (?arret_des_threads@mux@@2_NA)Compil OK et .lib et .dll générés
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 #ifdef __DLL__ #define IMPEXP __declspec(dllexport) #else #define IMPEXP __declspec(dllimport) #endif ... class IMPEXP mux{... public : static bool arret_des_threads; };
et dans le .h de DLL2, je code de cette facon:avec le linkage DLL1.lib effectué (.dll et .h bien déplacé dans le bon répertoire).
Code : Sélectionner tout - Visualiser dans une fenêtre à part #include "Debug\DLL1.h"
Bref, dans la méthode de ma classe DLL2 qui utilise arret_des_threads, j'utilise par exemple cette syntaxe :Je pense que c'est ici que ca bug car quand j'utilise while(1) au lieu de while(! mux::arret_des_threads), ca compile sans soucis DLL2.
Code : Sélectionner tout - Visualiser dans une fenêtre à part while(! mux::arret_des_threads){... //même pas une modif en fait, juste un test
Merci si quelqu'un a la soluce !
Tu as bien défini ta variable statique dans un .cpp ?
Tu peux aussi passer par une fonction, ce sera peut-être mieux que d'aller bidouiller une variable publique directement, surtout dans ce cas.
Dans DLL1.cpp, je définis ma variable de cette façon :
c'est défini correctement je pense.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 #include "dll_mux.h" bool mux::arret_des_threads; ...
Comment ça "passer par une fonction" ?
Peut-être qu'il faut remettre un petit IMPEXP devant la définition de ta variable statique.
Comment ça "passer par une fonction" ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 class IMPEXP mux{ private : static bool arret_des_threads; public : static void arreter_threads(); }; void mux::arreter_threads() { arret_des_threads = true; }
ah ok je n'avais pas compris !Envoyé par Laurent Gomila
J'essaie tout cela, merci Laurent
J'en remet une couche
J'ai un projet (PROJ.cpp & PROJ.h) qui exploite une DLL (DLL.lib, DLL.dll et DLL.h). Dans PROJ.h, je définie une classe abstraite (classe_abs).
Dans DLL.h , je déclare une classe concrète (classe_con) qui découle de cette classe abstraite.
(je précise que lors de la création de ma dll , j'ai bien joint au projet la partie de PROJ.h contenant déclaration de classe_abs).
Code : Sélectionner tout - Visualiser dans une fenêtre à part class IMPEXP classe_con : public classe_abs{...}
Dans le main de PROJ.cpp, j'instancie:
Mon programme compile mais plante lors de l'exécution lorsqu'il arrive sur cette dernière ligne, comme si il ne trouvait pas classe_con alors que j'ai bien linké DLL.lib,créé un include de DLL.h, et déplacé DLL.dll dans le bon repertoire.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 vector <classe_abs *> fee(nb_elem); /*puis je fais dans une boucle*/ fee[i] = new classe_con(...);
Que de soucis pour maitriser les dll ...
NB : N'aurais-tu pas un site bien conçu pour bien maitriser les dll en c++ ?
Que dit le message d'erreur ? Tu peux essayer de déboguer ? Tu utilises quel environnement de programmation ?
Voici le message d'erreur :Envoyé par Laurent Gomila
Code : Sélectionner tout - Visualiser dans une fenêtre à part Exception non gérée à 0x7848144b dans exec_multiplexeur.exe:Point d'arrêt utilisateur.Niveau debogage je suis allé jusqu'à la ligne pour confirmer que c'est bien fee[i] = new classe_con(...); qui bug.Envoyé par Laurent Gomila
Néanmoins , vue que j'avais déjà réalisé ce programme en un seul projet sans DLL (avec des .cpp et .h uniquement) je sais que cette ligne est censée fonctionner.
Je programme sous VS.net 2003 (OS : Win 2000 Pro).Envoyé par Laurent Gomila
Il faudrait débogueur un peu plus en profondeur pour voir ce qui se passe précisément.
Je précise pour l'erreur que la flèche verte sous VS indique la lignede dbgheap.c ...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 _CRTIMP int __cdecl _CrtIsValidHeapPointer( const void * pUserData ) { ... }
Et en remontant la pile d'appels ?
Pour être encore plus précis, même si je ne comprend pas tout :
La ligne qui fait bugger quand je rentre en détail dans le prog (Pas a pas détaillé) est celle ci :qui se trouve dans dbgheap.c
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 #endif /* _WIN64 */ { return HeapValidate( _crtheap, 0, pHdr(pUserData) ); }
Ensuite les indications de la pile d'appels sont les suivantes :
Flèche jaune bloquée sur : ntdll.dll!7848144b();
Flèche verte bloquée sur : dll.dll ("ca, c'est ma dll qui contient la classe concrete")!_CrtIsValidHeapPointer(const void * pUserData=0x006545c8) Ligne 1807
Et en remontant un peu plus y a pas une fonction qui vient de ton code à toi ?
En même temps, l'allocation (le new) peut foirer en mode debug parcequ'on a modifié illégalement une autre zone mémoire avant (écriture après la fin d'une chaine, d'un tableau, pointeur non initialisé). En debug, aussi, aucune variable n'est initialisée à 0.
Pour revenir sur les histoires de DLL...
A mon avis utiliser un define __DLL__ aussi générique est très dangereux... Quid d'une DLL incluant une autre DLL ? Les deux définissent __DLL__ et pourtant, l'une fait de l'import l'autre de l'export....
En général j'utilise plutot:
Dans les headers:
Dans le fichier qui crée le header précompilé:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 #ifndef MYLIBRARY_API #ifndef MYLIBRARY_LIB #define MYLIBRARY_API __declspec(dllimport) #else #define MYLIBRARY_API #endif #endif class MYLIBRARY_API xxxx { };
Comme ca, pas de risque que deux dlls se mordent la queue. Pas de risque non plus d'oublier le define... Et surtout, ca gere automatiquement static library, dll, etc...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 #ifdef _USRDLL #define MYLIBRARY_API __declspec(dllexport) #else #define MYLIBRARY_API #endif
Ce que conseille Visual, c'est de mettre tout dans le header, et le define dans les options du projet de la DLL:
http://www.developpez.net/forums/sho...42&postcount=6
Bonjour,
Mon probleme quoique different a sa place dans cette discussion, c'est pourquoi je la relance.
Ma dll est en fait un plugin, ce plugin doit comporter une classe qui hérite d'une autre dont toutes les méthodes sont virtuelles. La dll est chargée à l'aide de "LoadLibrary". Dès lors, comment faire pour instancier la classe de la dll ? Suis je obligée d'imposer aux createurs de plugins de fournir dans leur dll une fonction qui instancie leur classe et renvoie un pointeur dessus ou puis je l'instancier moi meme ?
Merci
Tu es obligé de spécifier dans l'interface de la DLL une fonction de création. Cette fonction doit être déclarée extern "C" et toujours être exportée sous le même nom, et c'est ce nom que cherchera ton programme.
Ou bien, tu peux exiger qu'un fichier de config soit fourni avec le plugin, pour indiquer le nom de la fonction à appeler. Mais dans tous les cas, son prototype doit être fixe, et c'est à toi de l'imposer.
Partager