Export de fonctions EXE -> DLL et DLL -> EXE

Export de fonctions EXE -> DLL et DLL -> EXE - C++ - Programmation

Marsh Posté le 22-12-2004 à 18:27:33    

Bonjour,  
Alors ce problème est assez compliqué, donc je vais essayer d'être le plus clair possible.
 
Je fais un programme qui pourra charger dynamiquement des modules contenus dans des DLL.
 
Pour cela, les DLL exporteront des fonctions qui seront utilisables dans l'EXE. Pour éviter de recopier inutilement des fonctions dans les DLL, l'EXE exportera également des fonctions.
 
J'ai réussi à exporter mes fonctions, or, quand j'utilise par exemple une fonction qui vient d'une DLL qui exporte une chaine de type std::string, cela provoque un BreakPoint (message n° sur le screenshot), puis quand je clique sur continuer l'execution du projet, j'obtiens le message n°2.
 
http://rclsilver.free.fr/question_dll/exec.JPG
Pourtant, d'apres ces 2 screenshots qui suivent, mes fonctions sont bien exportés correctement :
 
http://rclsilver.free.fr/question_dll/export_dll.JPG
http://rclsilver.free.fr/question_dll/export_exe.JPG
 
Je ne comprends pas, en plus, on peut remarque (cf 1er screenshot) que l'execution qui provoque le breakpoint est bien executée... donc ça doit venir d'une libération non faite ou quelque chose comme ça non ? Enfin je sais pas du tout (c'est pour ça que je demande).
 
Si vous voulez des informations complémentaires, n'hésitez pas à demander.
 
A oui j'allais oublier :
- J'utilise Visual Studio 6.0 (et sur VS7 ça fait la même erreur)
- Le projet est disponible sur http://rclsilver.free.fr/question_dll/test_dll.zip
 
Merci d'avance, j'espère que j'ai été clair :)

Reply

Marsh Posté le 22-12-2004 à 18:27:33   

Reply

Marsh Posté le 22-12-2004 à 18:33:41    

Quake 2 utilise un procede analogue pour assurer la communication entre le jeu et le moteur. Jette un oeil au code source, peut etre tu trouveras ton bonheur.
 
Et sinon, j'avais entendu une histoire comme quoi il fallait pas transferer des strings entre differents modules ( a verifier ). As tu compilé l'exe et la dll avec le meme compilateur?

Reply

Marsh Posté le 22-12-2004 à 18:36:19    

Je n'ai pas regardé vraiment ton code mais l'erreur qui s'affiche dans ton 2eme message me laisse penser que ton programme essaie de libérer de la mémoire qui a été allouée avec une autre version des libc.
 
Essaie de passer ton prog et ta DLL en "Multithreaded DLL" (dans code generation). Comme cela ils auront tous les 2 une dépendance vers mscvrt.dll qui sera leur libc commune.
 

Reply

Marsh Posté le 22-12-2004 à 18:37:47    

oui l'exe et la dll sont tous deux compilés avec VSC++ 6.0. Sinon pour ce qui est des strings, en fait ça me le fait un peu avec tout. Par exemple j'ai une class dans le .exe et si j'execute une de ses méthodes dans la DLL, ça me produit la meme erreur :/ donc voila je bloque.

Reply

Marsh Posté le 22-12-2004 à 18:41:42    

je suis passé en Multithreaded DLL avec les options suivantes  
http://rclsilver.free.fr/question_dll/options.JPG et ça me fait la meme erreur :o

Reply

Marsh Posté le 22-12-2004 à 18:47:32    

Il ne faut pas utiliser la STL dans l'export des dll. Chaque (version de) compilo utilise sa propre STL. Donc VC++ 7 croie manipuler son type string, mais c'est celui de VC++ 6, donc boum.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 22-12-2004 à 18:51:44    

les 2 projets sont compilés avec VS6 là (je précisais juste qu'avec VS7 ça faisait la meme erreur)

Reply

Marsh Posté le 22-12-2004 à 19:03:45    

Tu as recompilé exe & dll avec la runtime dll ?
Je te dit ça car tu seras pieds & poings liés à une version précise d'un compilo.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 22-12-2004 à 19:06:50    

je comprends pas la question ? que veux tu dire pieds et poings liés a une version de compiloo ? tu as une solution pour mon pb ?

Reply

Marsh Posté le 22-12-2004 à 19:12:20    

bon, ca ca peut pas marcher.  
Pourquoi ?
parce que le string retourné par ta DLL est alloué par la DLL (lors de la recopie pour le retour), mais, pas de bol, c'est l'exe qui va effeectuer la desallocation => kaboom
 
Tout ceci grace a ces foutus CRT. Si tu alloue de la memoire dans une DLL, alors c'est cette DLL qui doit la désallouer. C'est relou. De plus comme l'as dit helloworld, STL et DLL ca chie du boudin.  
 
Solution ? pas grand chose a faire, si ce n'est eviter d'utiliser la STL dans ce bins.
 
désolé.


Message édité par chrisbk le 22-12-2004 à 19:12:53
Reply

Marsh Posté le 22-12-2004 à 19:12:20   

Reply

Marsh Posté le 22-12-2004 à 19:28:20    

bah ouais, mais par exemple, quand je veux exporter une class (du moins une instance de class) ça me fait pareil :o donc c'est un peu pénible ça :o

Reply

Marsh Posté le 22-12-2004 à 19:30:24    

bin, fo pas faire des retours par copie, fo faire des retour par pointeur. Mais attention ! Si le code de tes fonctions n'est pas accessible a la compilation pour ton exe, alors ces fonctions devront etre virtuelles.
 

Reply

Marsh Posté le 22-12-2004 à 19:39:23    

donc si je comprends bien, je dois passer des pointeurs pour mes méthodes et pour les string, passer un buffer qu'on remplit serait une solution ?

Reply

Marsh Posté le 22-12-2004 à 19:41:43    

simplement : fo que les allocs soient faite au meme endroit que les desallocs. Ca exclue les retour par valeur de classe (qui d'ailleurs sont déconseillée)
 
Apres, ca te laisse un certain champ de manoeuvre pour les magouilles, a coup de fonctions
 

Reply

Marsh Posté le 22-12-2004 à 19:44:27    

ok je vais faire quelques tests, je vous direz quoi, merci de votre aide :)

Reply

Marsh Posté le 22-12-2004 à 20:10:09    

chrisbk a écrit :

bon, ca ca peut pas marcher.  
Pourquoi ?
parce que le string retourné par ta DLL est alloué par la DLL (lors de la recopie pour le retour), mais, pas de bol, c'est l'exe qui va effeectuer la desallocation => kaboom


Ben si la CRT est commune et partagée sous forme de dll, c'est censé résoudre le problème. Il faut que la dll et l'exe soient en CRT DLL.
D'où ma question
"Tu as recompilé exe ET la dll avec la runtime dll ?"
 

Citation :

que veux tu dire pieds et poings liés a une version de compiloo ?


Je ne sais pas ce que tu fais avec ces dll, mais j'espère que c'est pas pour des plugin ou un truc du genre. Ton exe et toutes ses dll doivent être compilés avec le même compilo. Pas possible par exemple de patcher une ancienne version avec un nouveau compilo, etc... Si tu as refourgué ton soft compilé avec VS6 et depuis t'es passé à VS7, ben faut avoir une gestion très rigoureuse des versions de ton soft. Pas question qu'un tiers fournisse sa dll aussi.
 
La solution ? Faut voir ton utilisation. Si c'est une bidouille interne reste comme ça. Si tu cherches la souplesse, faut d'orienter vers COM.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 22-12-2004 à 20:23:12    

le .exe sera un programme en fait, et les DLL seront des modules que le programme chargera et dechargera dynamiquement. certaines fonctions du .exe seront utilisées dans le .dll et les fonctions des dlls ne seront utilisées dans la dll et dans le .exe. quand tu dis faut orienter vers COM, c'est quoi COM ? ensuite, le developpement de modules sera assez reservé aux developpeurs de ce programme (on est 2) et on utilise la meme version de vs, donc pas de pb sur ce point. dernier truc : "Il faut que la dll et l'exe soient en CRT DLL" j'ai cherché un peu... je vois pas ce que tu veux dire, c'est ce que m'a dit titi_4js tout a l'heure ? Multithreaded DLL ?

Reply

Marsh Posté le 22-12-2004 à 20:30:39    

Oui, les 2 doivent être en [Multithreaded] Dll (Multithreaded c'est accessoire, à toi de voir). Les 2 doivent utiliser la même chose.
COM, ben heu, si tu connais pas oublie, c'est une usine à gaz et apparement inutile pour toi.
 
Ca me fait bizarre quand même ton exe qui utilise des dll qui elles-même utilisent l'exe. En général on crée une autre dll commune à tout le monde. Les dépendances croisées c'est pas top.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 22-12-2004 à 20:44:59    

!! alors je crois que ça irait la ! en fait mes 2 projets etaient dans le meme workspace et le changement ne prenait pas effet! avec Multithreaded dll ça marche apparement ! je vais faire qq tests un peu plus poussés je vous dit quoi ! merci deja pour votre aide !! c'est super !!

Reply

Marsh Posté le 22-12-2004 à 21:24:11    

Voila je voulais tous vous remercier, car en compilant avec Multithreaded DLL, ça marche nickel !! Un grand merci, on cherchait depuis pas mal de temps ! MERCI !

Reply

Marsh Posté le 22-12-2004 à 23:02:37    

oué mais fais gaffe quand meme :o CRT are everywhere :o

Reply

Marsh Posté le 22-12-2004 à 23:02:59    

(si jamais t'utilise des libs genre zlib, libjpeg & cie, pense a les recomp en multithread...)

Reply

Marsh Posté le 22-12-2004 à 23:06:05    

oky, merci des conseils :)

Reply

Marsh Posté le 23-12-2004 à 01:30:38    

Tu peux utiliser la CRT Dll sans être multithread ("Dll de debogage" je crois).


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 23-12-2004 à 10:11:47    

(je bosse avec rclsilver la dessus)
Vu qu'on voulait contourner l'utilisation du CRT en DLL,
avec l'explication de chrisbk, j'ai surchargé les operateurs new/delete/new[]/delete[], dans la dll, qui font appel a des fonctions exportés de l'exe qui elles meme appellent les operateurs new/delete/new[]/delete[] de l'executable, et ainsi ca fonctionne bien.
Merci pour votre aide !


---------------
-( BlackGoddess )-
Reply

Marsh Posté le 23-12-2004 à 10:16:53    

BlackGoddess a écrit :

(je bosse avec rclsilver la dessus)
Vu qu'on voulait contourner l'utilisation du CRT en DLL,
avec l'explication de chrisbk, j'ai surchargé les operateurs new/delete/new[]/delete[], dans la dll, qui font appel a des fonctions exportés de l'exe qui elles meme appellent les operateurs new/delete/new[]/delete[] de l'executable, et ainsi ca fonctionne bien.
Merci pour votre aide !


 
 
tiens, oué, pourquoi pas, perso je passe par des factory et un truc->deleteThis(); (et constructeur / destructeur privé pour eviter les blagues)


Message édité par chrisbk le 23-12-2004 à 10:17:04
Reply

Marsh Posté le 23-12-2004 à 11:35:52    

Quel est le probleme avec la CRT en dll ? Du coup elle est dupliquée dans chacune de tes dll...


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 23-12-2004 à 14:34:34    

chrisbk a écrit :

tiens, oué, pourquoi pas, perso je passe par des factory et un truc->deleteThis(); (et constructeur / destructeur privé pour eviter les blagues)


 
pour le passage de paramètre ca pose toujours des problemes non ? du moins on a beaucoup moins de liberté, il faut toujours penser à ce qui se fait derriere suivant l'utilisation des paramètres ?
 

HelloWorld a écrit :

Quel est le probleme avec la CRT en dll ? Du coup elle est dupliquée dans chacune de tes dll...


 
seules les parties utilisées son dupliquées ... par exemple pour un helloworld sous vc++7.1:
avec les crt dll, l'exe fait 5 ko, mais appelle une dll de 480ko et une de 360 (de tete)
avec les crt statiques, l'exe fait 48ko.
 
ce que je voudrais arriver à faire c'est pouvoir intégrer statiquement à l'executable seuls les bouts de la sl/stl dont j'ai besoin, les exporter et faire en sorte que la dll les utilise ... je ne sais pas si c'est possible :/


---------------
-( BlackGoddess )-
Reply

Marsh Posté le 23-12-2004 à 14:37:44    

BlackGoddess a écrit :

pour le passage de paramètre ca pose toujours des problemes non ? du moins on a beaucoup moins de liberté, il faut toujours penser à ce qui se fait derriere suivant l'utilisation des paramètres ?


 
heuh j'ai pas tout compris ? :d
 

Reply

Marsh Posté le 23-12-2004 à 14:43:59    

si tu as un membre (coté dll, appelé par l'exe)
void membre(std::string &s)
{
  s += "abc";
}
 
si cela force a faire une reallocation interne a la chaine, boom.
je vois pas comment l'utilisation de factory pourrait y changer ?
a moins de redéfinir les classes de la sl/stl dont tu as besoin sur le meme design factory ?


---------------
-( BlackGoddess )-
Reply

Marsh Posté le 23-12-2004 à 17:41:27    

BlackGoddess a écrit :

ce que je voudrais arriver à faire c'est pouvoir intégrer statiquement à l'executable seuls les bouts de la sl/stl dont j'ai besoin, les exporter et faire en sorte que la dll les utilise ... je ne sais pas si c'est possible :/


Non pas possible. Votre histoire d'exe qui exporte des fonctions ça me gêne quand même. Comment se passe le link avec cet exe ? Vous faite un LoadLibrary dessus ou c'est compilé avec le .lib ?
J'espère que c'est un LoadLibrary/GetModuleHandle, sinon si le mec renomme l'exe y'a plus rien qui marche.
Pour le coup l'exe se comporte comme une dll et inversement. Si jamais l'exe est lié en statique à la dll, c'est le serpent qui se mord la queue...
Pour le coup de la taille réduite, faut voir. Si tout ce bazard (car c'est du bazard ;)) c'est pour économiser 100Ko, c'est moyen... Certe tu économises ce que tu n'utilises pas, mais tu dupliques ce que tu utilises partout. Jette un oeil rapide au projet :
- alors on a un exe qui se lie dynamiquement à des dll
- ces dll se lient dynamiquement à l'exe
- donc l'exe est aussi une dll et exporte des fonctions
- ca pose probleme au niveau des CRT, donc l'exe exporte aussi les fonctions nécessaires pour allouer/supprimer
- ces fonctions appellent les bons new / delete
- on fait fonctionner tout ça en surchargeant les opérateurs d'allocation/libération
- donc si vous voulez faire une dll n'oubliez pas le lier à l'exe et d'utiliser les new/delete surchargés
ah hem, c'est tordu non ?


Message édité par HelloWorld le 23-12-2004 à 17:46:12

---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 25-12-2004 à 10:40:17    

mmh oui tu as raison, on va revoir le design, tu m'as fait prendre un peu de recul et c'est vrai que c'est un peu tordu.
 
les exportations de l'exe venaient du fait que je voulais laisser les modules utiliser le plus de fonctionnalités possibles de l'executable (on s'est inspiré d'une gestion de module en C unix, le format elf permet les echanges comme ca beaucoup plus facilement)
j'ai pensé utiliser des factories dans les 2 sens (exe -> dll et dll -> exe) mais cela va etre beaucoup plus contraignant.
existe-t-il d'autres solutions ?


---------------
-( BlackGoddess )-
Reply

Marsh Posté le 29-12-2004 à 00:40:25    

Normalement ce que tu exportes depuis ton exe tu peux le mettre dans une dll commune utilisée par ton exe et toutes tes autres dll.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 29-12-2004 à 00:59:20    

oui, mais le truc c'est qu'on voudrait pas que ça s'etale partout en fait, on voudrait un minimum de fichiers :o

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed