probleme de nom décoré DLL C (résolu)

probleme de nom décoré DLL C (résolu) - C++ - Programmation

Marsh Posté le 25-04-2004 à 17:30:27    

Bonjour.
 
J'essaye desespérément depuis plus d'une semaine de faire une dll compatible en C mais qui en interne est en C++
 
j'ai reussi a la créer et a l'utiliser sous visual.
 
mais quand je tente de l'utiliser sous CVI (compilateur C) je bloque sur le probleme suivant :
 
j'ai 2 fonctions voici le .H de ma dll :  
 
________________________________________________
 
#ifdef __cplusplus
    extern "C" {
#endif
 
 int  __declspec(dllexport) _stdcall InitGdiplus(void);
 void __declspec(dllexport) _stdcall CloseGdiplus(void);
 
#ifdef __cplusplus
    }
#endif
 
________________________________________________
 
j'ai egalement un .def :  
 
________________________________________________
 
LIBRARY LSGdiplus
 
EXPORTS
 
InitGdiplus
CloseGdiplus
 
________________________________________________
 
Et donc sous CVI lorsque j'appelle l'une de ces fonction le compilateur me jete en me répondant :  
 
undefined symbol '_InitGdiplus@0' not defined in main.c
undefined symbol '_CloseGdiplus@0' not defined in main.c
 
j'ai essayé plusieurs choses comme par exemple de mettre dans mon .def :
 
InitGdiplus = _InitGdiplus@0
 
mais rien n'y fait et pourtant je me répéte, sous visual je ne rencontre aucun probleme pour appeller ces fonctions.
 
Je pense qu'il doit y avoir un parametre a modifier dans le projet sous visual pour résoudre ce probleme de nom décoré.
 
Dernier détail, si je regarde ma dll je vois ceci :  
 
pour le premier .def :  
 
Export Table
 
 Name: LSGdiplus.dll
 Characteristics: 00000000
 Time Date Stamp: 408bd341
 Version: 0.00
 Base: 00000001
 Number of Functions: 00000002
 Number of Names: 00000002
 
Ordinal Entry Point Name
0000 00001080 CloseGdiplus
0001 00001030 InitGdiplus
 
pour le second .def (cad en mettant InitGdiplus = _InitGdiplus@0):
 
Export Table
 
 Name: LSGdiplus.dll
 Characteristics: 00000000
 Time Date Stamp: 408bd341
 Version: 0.00
 Base: 00000001
 Number of Functions: 00000004
 Number of Names: 00000004
 
Ordinal Entry Point Name
0000 00001080 CloseGdiplus
0001 00001030 InitGdiplus
0002 00001080 _CloseGdiplus@0
0003 00001030 _InitGdiplus@0
 
mais pourquoi tant de haine?
voila ma balize de détresse est lancée.


Message édité par giova le 26-04-2004 à 11:18:54
Reply

Marsh Posté le 25-04-2004 à 17:30:27   

Reply

Marsh Posté le 25-04-2004 à 17:49:16    

T'as vraiment besoin d'un DLL ? Une lib tout simple statique serait pas plus pratique dans ton cas ?
 
Cordialement,  
 Xter.
 


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 25-04-2004 à 18:34:00    

euh bonne question :)
 
bah en fait je suis en stage en entreprise, c'est ce que l'on m'a demandé, c'est pour pouvoir utiliser gdiplus.dll qui est gratuit plutot que la dll payante de CVI.
 
je ressort d'un formation ou j'ai juste appris le C++ traditionnel et encore!! je n'ai pas vu: les STL , MFC, sigleton, heritage multiple, et les exeptions.
 


Message édité par giova le 25-04-2004 à 18:35:27
Reply

Marsh Posté le 25-04-2004 à 18:42:30    

Si je comprends bien la DLL dont tu nous parles ne t'appartient pas, et on peut raisonnablement penser qu'elle est correctement codée. Ta question est donc comment de manière gfénérale utliser une DLL dans ton programme ? C'est bien ca ?
 
La DLL est livrée avec quoi d'autre : .def, .h ?


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 25-04-2004 à 18:49:06    

Pourquoi as tu besoin d'un .def??
C'est plus d'actualité, ça.
A+,

Reply

Marsh Posté le 25-04-2004 à 19:32:15    

xterminhate : gdiplus est plus que raisonnablement codée a mon avis, elle est carrement fournie de base avec VC 2003
 
gilou: et bien parceque je me suis basé sur un code donné en exemple, sur les dll je suis autodidacte a 100%
 
J'avoue que je maitrise pas grand chose dans tout ca, il m'a semblé comprendre que le .def servait a exporter les fonctions sous forme non décorés, mais j'ai essayé aussi sans le .def car (j'ai encore cru comprendre que ) mes __declspec(dllexport) suffisent a exporter mes fonctions.

Reply

Marsh Posté le 25-04-2004 à 19:33:13    

giova a écrit :


je ressort d'un formation ou j'ai juste appris le C++ traditionnel et encore!! je n'ai pas vu: les STL , MFC, sigleton, heritage multiple, et les exeptions.

le C quoi

Reply

Marsh Posté le 25-04-2004 à 19:33:15    

j'oubliais, meme avec le code que mon "patron" m'a donné en exemple je rencontre EXACTEMENT le meme probleme.

Reply

Marsh Posté le 25-04-2004 à 19:34:21    

Taz a écrit :

le C quoi


 
bah non !  
j'ai vu les classes, surcharge d'operateur, heritage simple, polymorphisme, classes et fonctions template, donc non pas du C :)

Reply

Marsh Posté le 25-04-2004 à 19:37:01    

j'ai pas d'expérience C++ utilisé par du C, mais je sens assez mal si y a des RTTI (virtual, dynamic_cast, etc) vu que ça demande un support d'exécution...

Reply

Marsh Posté le 25-04-2004 à 19:37:01   

Reply

Marsh Posté le 25-04-2004 à 19:38:27    

j'ai ultra vaguement vu les RTTI, en fait pour un exercice il nous expliquait comment l'utiliser.

Reply

Marsh Posté le 25-04-2004 à 19:42:22    

ben le polymorphisme ça demande des RTTI
 
d'ailleurs le extern "C" je l'ai jamais utilisé que pour déclarer du code C avec lequel je voulais linker, je suis pas sur du tout qu'on puisse s'en servir pour exporter du code ...

Reply

Marsh Posté le 25-04-2004 à 19:43:57    

et bien c'est exactement ce que je cherche a faire, exporter des fonctions en C qui apres en interne de la DLL (donc "invisible" pour le C) appellent ce qu'il faut comme il faut.


Message édité par giova le 25-04-2004 à 19:44:34
Reply

Marsh Posté le 25-04-2004 à 19:57:42    

je sais même si c'est possible ... :sweat:
 
je viens de faire un test : sur un truc très simple comme  
 

Code :
  1. extern "C"
  2. {
  3.   struct Foo
  4.   {
  5.     int sum;
  6.     int prod;
  7.   };
  8.   struct Foo test1(int a, int b);
  9. }
  10. #include <functional>
  11. struct Foo test1(int a, int b)
  12. {
  13.   struct Foo res;
  14.   res.sum  = std::plus<int>()(a, b);
  15.   res.prod = std::multiplies<int>()(a, b);
  16.   return res;
  17. }

ça marche
 
maitenant le simple fait d'inclure <iostream> fout tout en l'air alors ....
 
 

Code :
  1. #include <iostream>
  2. namespace
  3. {
  4.   class Bar
  5.   {
  6.   public:
  7.     virtual ~Bar()
  8.     {
  9.       std::cerr << "~Bar\n";
  10.     }
  11.   };
  12.   class Baz
  13.     : public Bar
  14.   {
  15.   public:
  16.     virtual ~Baz()
  17.     {
  18.       std::cerr << "~Baz\n";
  19.     }
  20.   };
  21. }
  22. void test2()
  23. {
  24.   Bar *o = new Baz;
  25.   delete o;
  26. }

j'ose pas penser

Reply

Marsh Posté le 25-04-2004 à 19:59:49    

je comprends même pas comment le premier exemple passe, puisque le deuxième me crache indéfiniment
 

Code :
  1. /usr/include/c++/3.3/bits/stl_function.h:549: error: template with C linkage


 
ça sent le dtc profond là

Reply

Marsh Posté le 25-04-2004 à 22:09:05    

giova a écrit :

xterminhate : gdiplus est plus que raisonnablement codée a mon avis, elle est carrement fournie de base avec VC 2003
 
gilou: et bien parceque je me suis basé sur un code donné en exemple, sur les dll je suis autodidacte a 100%
 
J'avoue que je maitrise pas grand chose dans tout ca, il m'a semblé comprendre que le .def servait a exporter les fonctions sous forme non décorés, mais j'ai essayé aussi sans le .def car (j'ai encore cru comprendre que ) mes __declspec(dllexport) suffisent a exporter mes fonctions.


Les .def, ca date de l'epoque ou microsoft n'avait pas les __declspec(dllexport)
Ca faisait la meme chose: declarer explicitement les noms des procedures appelables depuis l'exterieur (ie declarer les procedures exportees de la dll).
(Bon, un .def, ca fait aussi d'autres choses, qui sont parametrables aussi directement au niveau du compilo ou du linker)
Donc, utiliser les deux, ca fait double emploi, et ca risque meme de creer des pbs inutiles.
A+,


Message édité par gilou le 25-04-2004 à 22:10:18
Reply

Marsh Posté le 25-04-2004 à 22:15:17    

Citation :

Et donc sous CVI lorsque j'appelle l'une de ces fonction le compilateur me jete en me répondant :


 
CVI, kesako??
Tu as bien fait une lib associee a la DLL et tu linkes avec elle??
A+,

Reply

Marsh Posté le 25-04-2004 à 23:03:13    

Citation :

Code :
  1. int  __declspec(dllexport) _stdcall InitGdiplus(void);
  2. void __declspec(dllexport) _stdcall CloseGdiplus(void);



 
L'utilisation de dllexport et d'un fichier .def est redondante. C'est soit le dllexport, soit le .def. Enfin pour le C, pour le C++ seul dllexport permet l'export de classes.
 
Le problème vient donc peut-être de là. Il faudrait essayer de construire le projet sans le .def
 
Sinon ça pourrait éventuellement être un setting de compilation qui forcerait les conventions d'appel dans le projet de la dll et pas dans l'autre ...


Message édité par fli le 25-04-2004 à 23:04:03
Reply

Marsh Posté le 26-04-2004 à 10:49:40    

Tout d'abord, Merci les gars c'est vraiment sympa de me donner un coup de pousse.
 
Bon alors dans l'ordre des questions :
 
gilou : CVI est un soft de "National instrument" plutot dédié au monde de l'industrie c'est un IDE reposant entierement sur le C tu achete les librairie a la carte, certaines servent d'interface pour diverses capteurs de mesure, ce que je trouve genial avec CVI en tant que débutant, c'est que tu peux avec une facilitée enfantile créer des interfaces utilisateurs, tout se fait a la souris, ca t'ouvre pour chaque ellement de l'IUM une fenetre de parametres que tu saisi et ca te genere le code, a l'inverse depuis le code tu peux retourner dans ces fenetres de parametres, c'est tres intuitif et simple d'utilisation. Tu peux d'un simple clic demander a CVI qu'il te genere une dll compatible visual.
 
pour le lib, bah c'est un projet dll win32 donc quand je compile , oui ca me genere un .lib et voici comment apres j'importe ma dll :  
 
tout d'abord je copie le .dll dans system32, le .lib dans /lib/ de visual et dans /extlib/ de CVI, et enfin le .h dans /include/ de visual et de CVI.
 
je fais dans mon code un #include "madll.h", et dans les proprietes de mon projet, editeur de liens, entrée, dépendance supplementaire je met : madll.lib
 
c'est le seul moyen que je connaisse a l'heure actuelle pour importer la dll.  Petite précision, dans cvi je n'ai pas trouvé d'endroit où l'on peut specifier le .lib, j'ai placé ce fichiers dans le repertoire extlib, j'ai egallement essayé en le placant dans le répertoire du projet comme ca a été fait dans le code que l'on m'a donné en exemple et qui lui fonctionne.
 
fli : oui moi aussi je pense que ca doit etre un parametre a la con dans mon projet visual qui pose probleme et voici pourquoi je pense ca :  
si je me base sur l'exemple qui m'a été donné, et que je laisse tous les parametres du projet de ma dll par defaut, j'arrive a compilé mais quand je crée un nouveau projet console dans visual et que je tente d'importer puis utiliser les fonctions de ma dll, alors le compilateur de visual me sort la meme erreure de compilation que sous CVI : undefined symbol '_InitGdiplus@0' not defined in main.c  
 
du coup j'ai comparé 1 a 1 les parametre du projet donné en exemple avec ceux d'un projet vide et grace a ca, j'ai résolu le probleme sous visual, mais je le répéte sous CVI le probleme reste entier.
 
voici les parametres concernés (je les ai betement tous relevés certains sont plus que certainement inutile, principalement concernant les chemins avec Debug, mais bon...):  
 


Général:
 Repertoire de sortie: .\Debug
 Repertoire intermediaire : .\Debug
 
C/C++:
 
 General :  
  Detection des PB de portabilité : non
 
 Generation de code:
  Activation de la régénération minimale : Non
 
 Entete précompilé:
  Creation/Utilisation d'un entete précompilé: Générer Automatiquement
  Creation/utilisation d'un en-tete précompilé en specifiant un nom de fichier : stdAfx.h
  Fichier d'entete précompilé : .\Debug/NomDeLaDll.pch
 
 Fichier de Sortie:
  Emplacement d'un listing ASM : .\DEbug/
  Nom de fichier objet : .\DEbug/
  Nom de fichier objet : .\DEbug/
 
 Informations de consultation :
  Activation des informations de consultation : Inclure toutes les informations de consultation
  Fichier du navigateur : $(IntDir)/
 
Editeur de liens:
 
 General :
  Fichier de sortie : .\Debug/NomDeLaDll.dll
  Activation des liens incrémentiels: Non
  Suppresion de la banniere de démarrage : Oui
 
  (option) taper la version de la dll au format %d.%d où %d = nombre entier de 0 a n
 
 Deboguage :
  Génération d'un fichier de base de données du programme : .\Debug/NomDeLaDll.pdb
 
 Systeme :
  Sous Systeme : Non Défini
 
 Avancé :
  Biblioteque d'importation : .\Debug/NomDeLaDll.lib
 
Informations de consultation :  
 
 Général:
  Fichier de Sortie : .\Debug/NomDeLaDll.bsc


 
si pour l'un de ces parametres vous savez quelles concequences cela peut avoir sur mon probleme pourriez vous me l'expliquer brievement?


Message édité par giova le 26-04-2004 à 10:54:47
Reply

Marsh Posté le 26-04-2004 à 11:24:42    

honte a moi je vais me faire harakiri.
mon probleme etait un faux probleme, tout etait ok en fait, j'ai finallement trouvé, le pb se trouvait dans CVI j'ai trouvé comment lui donné a bouffer le .lib j'aurais du m'en douter tout de suite et ne pas m'egarer dans des hypotheses foireuses quand j'ai constaté que sous visual le probleme n'existait pas !
 
donc pour résumer pour exporter des fonctions d'une dll vers du C, il faut :
1) fixer les parametres du projet comme décrit ci dessus
2) dans le header procéder de la facon suivante :
 

Code :
  1. #ifdef __cplusplus
  2.     extern "C" {
  3. #endif
  4. TypeSortie __declspec(dllexport) _stdcall NomFonction(void);
  5. #ifdef __cplusplus
  6.     }
  7. #endif


 
et evidement la definition des fonctions dans le cpp doit coincider avec les prototypes dans le header.

Reply

Sujets relatifs:

Leave a Replay

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