Faire une DLL sous Visual .NET ?

Faire une DLL sous Visual .NET ? - C++ - Programmation

Marsh Posté le 08-03-2005 à 09:07:26    

Bonjour à tous et aux autres!
 
Je suis en 2ème année de BTS IRIS sur un projet étudiant, et je dois faire une DLL sous Visual Studio .NET.  [:tieumlar]  
Le problème, c'est que je n'arrive pas à exporter des méthodes et des classes utilisables dans un programme client. :cry:  
Je me sers de la classe CSerie contenue dans la DLL (qui contient également les méthodes lire() et ecrire() de la classe CSerie).
Est-il possible également de créer un objet de type CSerie dans un programme client en important la classe CSerie à partir de la DLL?
 
Merci pour vos réponses !!!


---------------
Est-ce de l'info que tu respires ? Arrête d'essayer de programmer, fais-le !
Reply

Marsh Posté le 08-03-2005 à 09:07:26   

Reply

Marsh Posté le 08-03-2005 à 09:10:38    

Oué, tu fais une DLL avec l'options 'export symbols' de cocher, pis apres tu lis les commentaires dans le code généré pour comprendre comment ca marche.
 

Reply

Marsh Posté le 08-03-2005 à 16:13:53    

:pt1cable: J'ai fait comme tu m'as dit, mais il y a un problème, je n'arrive pas à importer la classe dans le programme client. G mis :
extern "C" __declspec(dllimport) class Cserie;
Mais erreur  :fou:  ! Il me dit  que la partie à gauche de class Cserie a été ignoré par le compilateur car il n'y a pas de déclaration de variable.
J'utilise un pointeur sur fonction crée grâce à un handle et GetProcAddress(). Mais même lorsque je déclare la classe Cserie dans le programme client et que je crée un objet de type Cserie, je ne peux pas utiliser le pointeur de fonction crée (pfn_Lire()) avec cet objet, car pfn_Lire n'est pas de type Cserie  :sweat: .
 
Auriez-vous une idée ? :ange:  
 
Merci d'avance !!! [:alucard]


---------------
Est-ce de l'info que tu respires ? Arrête d'essayer de programmer, fais-le !
Reply

Marsh Posté le 08-03-2005 à 16:15:16    

Tu la fait en quel langage ta DLL ? :heink:

Reply

Marsh Posté le 08-03-2005 à 17:53:28    

Code :
  1. #ifdef COMPILE_MYLIB_DLL
  2. #define MYLIB_EXPORT __declspec(dllexport)
  3. #else
  4. #define MYLIB_EXPORT __declspec(dllimport)
  5. #endif
  6. class MYLIB_EXPORT Cserie
  7. {
  8.     /* ... */
  9. };


 
http://forum-images.hardware.fr/icones/1/recherche.gif


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

Marsh Posté le 08-03-2005 à 22:20:24    

FlorentG a écrit :

Tu la fait en quel langage ta DLL ? :heink:


 
en c++


---------------
Est-ce de l'info que tu respires ? Arrête d'essayer de programmer, fais-le !
Reply

Marsh Posté le 08-03-2005 à 22:21:41    

HelloWorld a écrit :

Code :
  1. #ifdef COMPILE_MYLIB_DLL
  2. #define MYLIB_EXPORT __declspec(dllexport)
  3. #else
  4. #define MYLIB_EXPORT __declspec(dllimport)
  5. #endif
  6. class MYLIB_EXPORT Cserie
  7. {
  8.     /* ... */
  9. };


 
http://forum-images.hardware.fr/icones/1/recherche.gif


 
Ca je l'ai mis dans le code ma DLL, mais dans le programme client, comment je l'importe cette classe?


---------------
Est-ce de l'info que tu respires ? Arrête d'essayer de programmer, fais-le !
Reply

Marsh Posté le 08-03-2005 à 23:16:02    

Pareil.

Reply

Marsh Posté le 08-03-2005 à 23:19:11    


 
Ok mici, je vais essayer ! [:tieumlar]


---------------
Est-ce de l'info que tu respires ? Arrête d'essayer de programmer, fais-le !
Reply

Marsh Posté le 08-03-2005 à 23:20:36    

Sans rien faire. Si tu lis le code, c'est pour exporter qu'il faut définir COMPILE_MYLIB_DLL (dans les projects settings de ta dll). Le .h reste inchangé entre code dll / client.


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

Marsh Posté le 08-03-2005 à 23:20:36   

Reply

Marsh Posté le 08-03-2005 à 23:23:19    

HelloWorld a écrit :

Sans rien faire. Si tu lis le code, c'est pour exporter qu'il faut définir COMPILE_MYLIB_DLL (dans les projects settings de ta dll). Le .h reste inchangé entre code dll / client.


 
 :bounce:  [:alucard]  [:tieumlar]  :bounce:  [:alucard]  [:tieumlar]  :bounce:


---------------
Est-ce de l'info que tu respires ? Arrête d'essayer de programmer, fais-le !
Reply

Marsh Posté le 08-03-2005 à 23:24:35    

"Il en faut peu pour être heureux, oui vraiment peu pour être heureux..." ;)


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

Marsh Posté le 08-03-2005 à 23:27:09    

HelloWorld a écrit :

"Il en faut peu pour être heureux, oui vraiment peu pour être heureux..." ;)


 
 
Je galère tlmt, je suis trop content d'avoir des réponses, merci à vous ! Je vais essayer, et je vous dirait si ça marche ou pas ! [:alucard]


---------------
Est-ce de l'info que tu respires ? Arrête d'essayer de programmer, fais-le !
Reply

Marsh Posté le 10-03-2005 à 09:08:37    

Je n'y arrive tjrs pas (g ptêt raté kek chose  [:neo morpheus] !)
Je vais vous mettre les sources, dsl pour la longueur  :ange:  
 
Le fichier de ma DLL : DLL_RS232.cpp
 

Code :
  1. // DLL_RS232.cpp : définit le point d'entrée pour l'application DLL.
  2. //
  3. #include "stdafx.h"
  4. #include "DLL_RS232.h"
  5. #include <iostream>
  6. #include <windows.h>
  7. using namespace std;
  8. BOOL APIENTRY DllMain( HANDLE hModule,
  9.                        DWORD  ul_reason_for_call,
  10.                        LPVOID lpReserved
  11.      )
  12. {
  13. switch (ul_reason_for_call)
  14. {
  15. case DLL_PROCESS_ATTACH:
  16. case DLL_THREAD_ATTACH:
  17. case DLL_THREAD_DETACH:
  18. case DLL_PROCESS_DETACH:
  19.  break;
  20. }
  21.     return TRUE;
  22. }
  23. // Il s'agit d'un exemple de variable exportée
  24. DLL_RS232_API int nDLL_RS232=0;
  25. // Il s'agit d'un exemple de fonction exportée.
  26. DLL_RS232_API DWORD Cserie::Ecrire(void *pbuf, DWORD pnb )
  27. {
  28. DWORD longueur = pnb;
  29. WriteFile(hcom, pbuf, longueur, &longueur, NULL);
  30. return (longueur);
  31. }
  32. ///////////////////////////////////
  33. DLL_RS232_API DWORD Cserie::Lire( void *pbuf, DWORD pnb )
  34. {
  35. ULONG longueur = pnb;
  36. ReadFile(hcom, pbuf, longueur, &longueur, NULL);
  37. return( longueur );
  38. }
  39. ////////////////////////////////////
  40. DLL_RS232_API Cserie::~Cserie()
  41. {
  42. CloseHandle(hcom);
  43. }
  44. // Il s'agit du constructeur d'une classe qui a été exportée.
  45. // consultez DLL_RS232.h pour la définition de la classe
  46. Cserie::Cserie( char *pnom )
  47. {
  48. DCB car_com; // structure système pour modif paramètres port de com
  49. COMMTIMEOUTS tim_com; // struct syst pour modif time out  
  50. // ouverture  
  51. hcom = CreateFile(pnom, GENERIC_READ | GENERIC_WRITE, 0, NULL,
  52.      OPEN_EXISTING, 0, NULL);
  53. if ( hcom == INVALID_HANDLE_VALUE ) {
  54.  cout << "Erreur ouverture" << endl;
  55.  return;
  56. }
  57. // parametrage en 9600 BPS, 8, N, 1  
  58. GetCommState( hcom, &car_com);
  59. car_com.BaudRate = CBR_9600;
  60. car_com.ByteSize = 8;
  61. car_com.StopBits = ONESTOPBIT;
  62. car_com.Parity = NOPARITY;
  63. SetCommState( hcom, &car_com);
  64. // parametrage du timeout : on se met en mode trame <=>
  65. // attente infinie sur debut trame, fin lecture sur timeout entre octets
  66. // principe retenu, quand repond = trame complète  
  67. // RQ : si param = 0 <=> non utilise
  68. // formule = delai = ( multiplier * nb of bytes ) + constant  
  69. GetCommTimeouts( hcom, &tim_com);
  70. tim_com.ReadIntervalTimeout =100; // timeout sur 100 ms entre caractères  
  71. tim_com.ReadTotalTimeoutMultiplier=0; // NC - delai fct du nombre de caractères non utilise
  72. tim_com.ReadTotalTimeoutConstant=100 ; // NC - lecture dure maxi 1 seconde
  73. tim_com.WriteTotalTimeoutMultiplier=0; // NC - pour ecriture  
  74. tim_com.WriteTotalTimeoutConstant=0; // NC - pour ecriture  
  75. SetCommTimeouts( hcom, &tim_com);
  76. }


 
Maintenant le fichier DLL_RS232.h
 

Code :
  1. //DLL_RS232.h
  2. // Le bloc ifdef suivant est la façon standard de créer des macros qui facilitent l'exportation  
  3. // à partir d'une DLL. Tous les fichiers contenus dans cette DLL sont compilés avec le symbole DLL_RS232_EXPORTS
  4. // défini sur la ligne de commande. Ce symbole ne doit pas être défini dans les projets
  5. // qui utilisent cette DLL. De cette manière, les autres projets dont les fichiers sources comprennent ce fichier considèrent les fonctions  
  6. // DLL_RS232_API comme étant importées à partir d'une DLL, tandis que cette DLL considère les symboles
  7. // définis avec cette macro comme étant exporté.
  8. #ifdef DLL_RS232_EXPORTS
  9. #define DLL_RS232_API __declspec(dllexport)
  10. #else
  11. #define DLL_RS232_API __declspec(dllimport)
  12. #endif
  13. // Cette classe est exportée de DLL_RS232.dll
  14. class DLL_RS232_API Cserie{
  15. public :
  16. Cserie( char * = "COM1" ); // nom du port de com  
  17. ~Cserie();
  18. DWORD Lire( void *buf, DWORD pnb=1);
  19. DWORD Ecrire( void * buf, DWORD pnb =1);
  20. private :
  21. HANDLE hcom;
  22. };
  23. extern DLL_RS232_API int nDLL_RS232;
  24. DLL_RS232_API DWORD Ecrire(void *pbuf, DWORD pnb );
  25. DLL_RS232_API DWORD Lire( void *pbuf, DWORD pnb );


 
Le fichier DLL_RS232.def

Code :
  1. LIBRARY DLL_RS232
  2. EXPORTS Lire
  3. Ecrire


 
////////////////////////////////////////////////////////////////////////
Maintenant le code de l'appli cliente:
 
Le fichier RS232_avec_DLL.cpp:
 

Code :
  1. // RS232_avec_DLL.cpp : définit le point d'entrée pour l'application console.
  2. //
  3. #include "stdafx.h"
  4. #include <iostream>
  5. #include <windows.h>
  6. #include "RS232_avec_DLL.h"
  7. using namespace std;
  8. int _tmain(int argc, _TCHAR* argv[])
  9. {
  10. //Chargement de la DLL et assignation de son identifiant à la variable hdll
  11. HMODULE hDLL = LoadLibrary("C:\\DLL_RS232\\Debug\\DLL_RS232.dll" );
  12. //Test si le handle a une valeur
  13. if (hDLL == NULL)
  14.  cout<<"Echec chargement de la DLL."<<endl;
  15. //Création d'un type de pointeur de fonction DLL_Function_pointeur dont la fonction prend 0 argument
  16. typedef int (WINAPI *DLL_Function_ptr_0arg) (void *pbuf, DWORD pnb );
  17. //Création de pointeurs sur fonctions à 0 paramètres de type DLL_Function_ptr_0arg
  18. DLL_Function_ptr_0arg pfn_Lire;
  19. //Récupération de l'emplacement de la fonction "menu"
  20. pfn_Lire = (DLL_Function_ptr_0arg)GetProcAddress(hDLL,"Lire" );
  21. //Appel de la méthode menu() à l'aide de son pointeur pfn_menu() affichant le menu principal de l'application
  22. // pfn_Lire();
  23. Cserie Mon_Objet;
  24. //Lecture sur le port série
  25. char Chaine_Lue[100];
  26. cout<<"Lecture sur le port serie :"<<endl;
  27. do
  28. {
  29.  if(Mon_Objet.Lire(Chaine_Lue)==1)
  30.  cout<<Chaine_Lue;
  31. }while(*Chaine_Lue != '\r');
  32. //Déchargement de la DLL chargée
  33. FreeLibrary(hDLL);
  34. //~Cserie Mon_Objet; Marche pô *T_T'
  35. return 0;
  36. }


 
Et finalement le fichier RS232_avec_DLL.h ! :pt1cable:  
 

Code :
  1. //RS232_avec_DLL.h
  2. #ifdef DLL_RS232_EXPORTS
  3. #define DLL_RS232_API __declspec(dllexport)
  4. #else
  5. #define DLL_RS232_API __declspec(dllimport)
  6. #endif
  7. // Cette classe est importée de DLL_RS232.dll
  8. class DLL_RS232_API Cserie{
  9. public :
  10. Cserie( char * = "COM1" ); // nom du port de com  
  11. ~Cserie();
  12. DWORD Lire( void *buf, DWORD pnb=1);
  13. DWORD Ecrire( void * buf, DWORD pnb =1);
  14. private :
  15. HANDLE hcom;
  16. };
  17. extern "C" __declspec(dllimport) DWORD Lire( void *buf, DWORD pnb=1);


 
Heu ben voilà koi !  :whistle:  
 
Je sais que c bcp de code d'un coup :sweat: , mais svp, vous pouvez jeter un petit coup d'oeil pour me dire ce qui ne va pas?
 
Merci bcp bcp d'avance !  :jap:


Message édité par Neo Morpheus le 10-03-2005 à 09:20:40

---------------
Est-ce de l'info que tu respires ? Arrête d'essayer de programmer, fais-le !
Reply

Marsh Posté le 10-03-2005 à 11:31:39    

Commence par récupérer dependency walker et regarde ce que ta dll exporte vraiment.
Ensuite vire ton .def et ton LoadLibrary/GetProcAddress/FreeLibrary et utilise le fichier .lib généré avec ta dll.
Pour la classe Cserie, DLL_RS232_API ne doit être mis que lors de sa déclaration (dans le .h).
nDLL_RS232, Lire, Ecrire ils servent à quoi ?


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

Marsh Posté le 10-03-2005 à 11:46:13    

HelloWorld a écrit :

Commence par récupérer dependency walker et regarde ce que ta dll exporte vraiment.
Ensuite vire ton .def et ton LoadLibrary/GetProcAddress/FreeLibrary et utilise le fichier .lib généré avec ta dll.
Pour la classe Cserie, DLL_RS232_API ne doit être mis que lors de sa déclaration (dans le .h).
nDLL_RS232, Lire, Ecrire ils servent à quoi ?


 
 
Lire permet de lire sur le port série, Ecrire permet d'écrire sur le port série et nDLL_RS232...euh... :whistle: ...c une m**** générée par visual lors de la création du projet que j'ai oublié d'enlever  :D


---------------
Est-ce de l'info que tu respires ? Arrête d'essayer de programmer, fais-le !
Reply

Marsh Posté le 10-03-2005 à 12:07:34    

Je disais ça parce que elles sont implémentées nul part...


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

Marsh Posté le 10-03-2005 à 13:17:50    

HelloWorld a écrit :

Je disais ça parce que elles sont implémentées nul part...


 
Si, elles sont là. C pas ça kil faut mettre?
 
Dans DLL.cpp:
 

Code :
  1. DLL_RS232_API DWORD Cserie::Ecrire(void *pbuf, DWORD pnb )
  2. {
  3. DWORD longueur = pnb;
  4. WriteFile(hcom, pbuf, longueur, &longueur, NULL);
  5. return (longueur);
  6. }
  7. ///////////////////////////////////
  8. DLL_RS232_API DWORD Cserie::Lire( void *pbuf, DWORD pnb )
  9. {
  10. ULONG longueur = pnb;
  11. ReadFile(hcom, pbuf, longueur, &longueur, NULL);
  12. return( longueur );
  13. }


---------------
Est-ce de l'info que tu respires ? Arrête d'essayer de programmer, fais-le !
Reply

Marsh Posté le 10-03-2005 à 13:24:39    

Ca c'est les fonctions membres de ta classe Cserie. Moi je parle de ça:

Code :
  1. DLL_RS232_API DWORD Ecrire(void *pbuf, DWORD pnb );
  2. DLL_RS232_API DWORD Lire( void *pbuf, DWORD pnb );


qui ne sont pas membres de Cserie...


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

Marsh Posté le 10-03-2005 à 13:59:05    

HelloWorld a écrit :

Ca c'est les fonctions membres de ta classe Cserie. Moi je parle de ça:

Code :
  1. DLL_RS232_API DWORD Ecrire(void *pbuf, DWORD pnb );
  2. DLL_RS232_API DWORD Lire( void *pbuf, DWORD pnb );


qui ne sont pas membres de Cserie...


 
A quoi elles vont servir si elles ne sont pas membres de la classe Cserie? Mon_Objet est de type Cserie, il ne pourra pas s'en servir. Ou alors g vraiment rien compris lol !


---------------
Est-ce de l'info que tu respires ? Arrête d'essayer de programmer, fais-le !
Reply

Marsh Posté le 10-03-2005 à 16:14:40    

Bah dans ce cas supprime les de ton .h, non ?

Reply

Marsh Posté le 10-03-2005 à 16:17:39    

Cserie::Lire() est une fonction différente de Lire().
C'est du C++ de base ça hein, rien à voir avec les dll.


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

Marsh Posté le 10-03-2005 à 21:20:41    

oui je sais que c différent, mais je comprenais pas pourquoi tu me disais de mettre les implémentaions de Lire() et Ecrire() vu qu'elle ne me servent pas si elles ne sont pas membres de Cserie.
Au fait, merci pour tout, j'ai réussi à faire cette fichue DLL. J'ai mis le .dll et le .lib dans le dossier Debug de l'appli cliente, j'ai mis extern "C" __declspec(dllimport) API_DLL_RS232 DWORD Ecrire(void *pbuf, DWORD pnb ); (idem pour Cserie::Lire()) dans le .h de l'appli cliente, ainsi que la déclaration de la classe dans ce même .h avec class API_DLL_RS232 Cserie{méthodes et variables membres};. Finalement, j'ai inséré le .lib et .dll dans le projet de l'appli cliente avec "insérer un élément existant". Voilà ! Merci pour tout !

Reply

Marsh Posté le 11-03-2005 à 10:48:51    

Ben si Lire() et Ecrire() ne servent pas, faut pas les mettre alors...
Enfin t'y est arrivé c'est ce qui compte.


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

Marsh Posté le 12-03-2005 à 14:21:59    

Salut JuJu ! Toujours pas trouvé de solution ? j'te plains, cela dit, bonne révision ce week end pour l'éco !

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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