Problême de DLL

Résolu
Gendal67 Messages postés 627 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 24 juillet 2011 - 30 oct. 2004 à 10:57
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 - 30 oct. 2004 à 19:11
Voila mon problême : Je souhaite créer une DLL qui contiendrais une classe que j'ai créee ! Quel est le moyen le +simple et le moins emcombrant pour pouvoir acceder à cette classe depuis un code d'executable ?

(quels mots clés mettres ? les mêmes que pour les fct ? comment y faire apppel ?)

Genda67, à votre service !

24 réponses

cosmobob Messages postés 700 Date d'inscription mardi 30 décembre 2003 Statut Membre Dernière intervention 27 janvier 2009 4
30 oct. 2004 à 17:51
enleve le void... je récapitule tout.

dans le .h (ds le projet de ta DLL):

extern "c++"
{
class string
{
__declspec(dllexport) String(); //pas de void ds le constructeur par défaut.
etc...
}
}

ds le .cpp de ta DLL:

ton DLLMain (facultatif); plus le code des fonctions de la classe:

string::string() // ne mets pas de void, normalement c'est sans.
{
this->val = new char[MAX_PATH];
lstrcpy(this->val, "");

this->fval = new char[MAX_PATH];
lstrcpy(this->val, "");

this->length = 0;
this->flength = 0;
}
etc..

dans le fichier main.cpp de ton exe maintenant:

#include "classes.h"

int main(int argc, char** argv)
{
string a;
a = "salut";
//etc

return 0;
}

aucun probleme lors de la compilation du main.cpp de l'exe (vu que les définitions des methodes de la classe se trouvent ds "classes.h"), et aucun probleme lors de son edition de lien si tu as correctement ajouté le .a crée avec la DLL ds les options de linkage.
ha j'oubliais. le code des fonctions de la classe ne doit pas etre dans le .h !!!! juste les entetes des methodes de celle ci!!
par exemple:
ds le .h
extern "c++"
{
classe exemple
{
private:
int valeur;
public:
__declspec(dllexport) exemple();
__declspec(dllexport) exemple(int valeurdebase);
__declspec(dllexport) void modifvaleur(int newval);
__declspec(dllexport) int getvaleur(void);
}
}

ds le .cpp de la DLL:
#include "exemple.h"

exemple::exemple()
{
valeur = 0;
}

exemple::exemple(int valeurdebase)
{
valeur = valeurdebase;
}

void exemple::modifvaleur(int newval)
{
valeur = newval;
}

int exemple::getvaleur(void)
{
return valeur; // pas besoin du this au fait.
}

etc..

t'inquiete pas besoin d'etre un génie :)

a++ ;)
3
cs_LordBob Messages postés 2865 Date d'inscription samedi 2 novembre 2002 Statut Membre Dernière intervention 11 mai 2009 9
30 oct. 2004 à 12:40
regarde dans le forum, il y a deja la question qui a été posé... de plus il y a plusieurs sources sur l'utilisation et la creation de dll... jettes-y un coup d'oeil...
Bob...

"La chance accorde ses faveur aux esprits avertis..."
0
Gendal67 Messages postés 627 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 24 juillet 2011 2
30 oct. 2004 à 13:15
Oui, mais pas ac les classes (juste les fonctions), ou alors je dois etre aveugle ou mal chercher...

Genda67, à votre service !
0
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
30 oct. 2004 à 13:53
Salut,
Le moyen le plus efficace pour l'utilisation d'une classe contenue dans une DLL, est de créer une fonction exportée ( dans cette même DLL) qui sert à instancier cette classe. Ainsi, un code exécutable appellera cette fonction pour utiliser cette classe. C'est la meilleure solution pour exporter les classes d'une DLL.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Gendal67 Messages postés 627 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 24 juillet 2011 2
30 oct. 2004 à 13:55
racpp, je t'en prie, tes paroles me plaisent, donne voir un exemple, je te prie!! Tu seras un ange!! ^^

Genda67, à votre service !
0
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
30 oct. 2004 à 14:18
Le problème d'utilisation des classes d'une DLL est connu chez les programmeurs en Visual Basic. Car ce dernier ne peut pas instancier une classe directement d'une DLL. Le problème se pose aussi quand on veut utiliser une DLL de manière dynamique ( sans le fichier .lib et .h) avec LoadLibrary() et GetProcAddress() en C++. C'est pour cela que la fonction d'instanciation est obligatoire pour ne pas limiter la portée de la DLL. Voici un exemple:
http://www.laboratoire-microsoft.org/articles/dev/dll/5/

Cette page est pour Visual Basic mais l'exemple de classe et de fonction d'instaciation sont en C++.
0
Gendal67 Messages postés 627 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 24 juillet 2011 2
30 oct. 2004 à 14:19
Oui !! Je viens de caller! Tu pe me mettre un code ou un truc pr résoudre cxe probleme et permettre d'instancier la classe stp ?? :)

Genda67, à votre service !
0
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
30 oct. 2004 à 15:11
met ton code ici et on verra comment arranger ça
0
Gendal67 Messages postés 627 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 24 juillet 2011 2
30 oct. 2004 à 15:28
Oki, vala :

/* le fichier .cpp de la DLL */

#include "Classes.h" // défini apres
#include <windows.h>

#define DLLEXPORT __declspec (dllexport)

BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                       DWORD reason        /* Reason this function is being called. */ ,
                       LPVOID reserved     /* Not used. */ )
{
    switch (reason)
    {
      case DLL_PROCESS_ATTACH:
        break;

      case DLL_PROCESS_DETACH:
        break;

      case DLL_THREAD_ATTACH:
        break;

      case DLL_THREAD_DETACH:
        break;
    }

    /* Returns TRUE on success, FALSE on failure */
    return TRUE;
}

/* le code de classes.h */

#if _MSC_VER > 1000
#pragma once
#endif

#ifndef _WINDOWS_H_
#include <windows.h>
#endif

#ifndef _STDIO_H_
#include <stdio.h>
#endif

#ifndef _IOSTREAM_H_
#include 
#endif

class String {

  public:

    String(void);
    String(int num);
    String(double num);

   // autres instructions...

 };

 String::~String(void) { 
     
   delete val;
   delete fval;  
  }
     
 String::String(void) {

   this->val = new char[MAX_PATH];
   lstrcpy(this->val, "");
   
   this->fval = new char[MAX_PATH];
   lstrcpy(this->val, "");
   
   this->length = 0;
   this->flength = 0;
  }

// autres définitions des fct....



Et mnt, comment permetre l'instanciation de cette classe sachant que je souhaiterais, si c'est possible, laisser l'intégralité (classe + sa définition) dans la DLL

g tenté cette méthode, en vain :

#define DLLIMPORT __declspec (dllimport)

// autres bidules...

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
  
  HINSTANCE hDLL;
  hDLL = LoadLibrary("Test.dll");
  
  String lol;
}
 


Alors, tu a sune solution miracle ? g essayé ac tous les DLLIMPORT et DLLEXPORT que l'on peut imaginer (je crois) et ça déconne tjs... :((( plz, help me!!!

Genda67, à votre service !
0
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
30 oct. 2004 à 16:15
Ok, je vais voir comment régler tout ça dès que j'ai un peu de temps.
0
Gendal67 Messages postés 627 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 24 juillet 2011 2
30 oct. 2004 à 16:16
Un tres grand merci en tt cas, si tu réussis (un grand merci déja si tu te donnes le mal d'essayer pour m'aider) !!!! :-))

Genda67, à votre service !
0
cosmobob Messages postés 700 Date d'inscription mardi 30 décembre 2003 Statut Membre Dernière intervention 27 janvier 2009 4
30 oct. 2004 à 17:03
perso (je viens d'essayer) ya aucun probleme a lier une classe qui est contenue ds une DLL, tant que c'est fait de maniere statique.

dans ton .h de ta classe string, tu mets:
extern "C++"
{
class String
{

public:
__declspec(dllexport) String();
__declspec(dllexport) String(const String &b);
etc...
}
}

ne pas oublier le __declspec(dllexport) (cest sous vs remarque, ptet un autre mot clé sous devc++) devant chaque methode publique de la classe.

le .h la est important quand tu compiles la DLL. une fois que ta DLL et ton fichier .lib ou .a ont été générées, t'as juste a rajouter ce .a au linkage pour le programme qui veut utiliser la DLL (et a avoir le .h dans le programme qui définit les entetes des méthodes de la classe), et à mettre la DLL a coté de l'exe...

Les problemes d'initialisation et d'instanciation dont t'a parlés racpp n'existent que quand tu lies ta DLL de maniere dynamique !!! (avec LoadLibrary)
Ya egalement un probleme quand tu utilises une classe C++ dans un autre langage, (comme visual basic), mais ici ce n'est pas le cas.

a++ ;)
0
Gendal67 Messages postés 627 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 24 juillet 2011 2
30 oct. 2004 à 17:08
Petit probleme : ton __declspec(dllexport) n'est pas le bienvenue chez dev-c++ lorsqu'il est mis devant un constructeur !!

Genda67, à votre service !
0
Gendal67 Messages postés 627 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 24 juillet 2011 2
30 oct. 2004 à 17:15
Dis voir, tu dis que pour que cela marche, il faut lier statiquement la DLL au programme...mais comment faire cela (je précise que je suis débutant ac les DLL!) ! Moi , je ne connais que LoadLibrary() pour charger une DLL ! Merci de répondre :-)

Genda67, à votre service !
0
cosmobob Messages postés 700 Date d'inscription mardi 30 décembre 2003 Statut Membre Dernière intervention 27 janvier 2009 4
30 oct. 2004 à 17:23
en ajoutant le .a (celui qui a été créé qd t'as crée la DLL) ds les options de linkage de ton .exe, la DLL est liée statiquement a ton exe (par ex; l'exe ne démarre pas si la DLL ne se trouve pas a coté de lui, ou ds le repertoire systeme de windows, et le message d'erreur est: 'L'application n'a pas pu démarrer car string.dll est introuvable. La réinstallation de cette application peut corriger ce problème'. etre lié statiquement veut bien dire ne pa pouvoir démarrer si la DLL n'est pas présente. l'exe peut démarrer si tu essayer de charger dynamiquement une DLL avec LoadLibrary, simplement cette fonction va te retourner NULL)

pour ce qui est du message d'erreur que te donne devc++ qd tu mets un __declspec(dllexport) devant un constructeur, cite le message d'erreur, ptet ca peut s'arranger (as tu mis extern "c++", comme jtai montré?). en tout cas ya pa de probleme avec vs, donc a mon avis ca doit etre possible avec dev...

a++ ;)
0
Gendal67 Messages postés 627 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 24 juillet 2011 2
30 oct. 2004 à 17:30
Oui, j'avais compris ce phénomene de linkage statique, ce que je ne call pas, c cmt statiquement tu appelles les fct de la dll ? comme des fct normales ? genre :

ma_function(int a, int b); // ?

ou :

__declspec(dllimport) ma_function(int a, int b); // ?

/* le message d'erreur ? lol, le voici :

(__declspec(dllexport) devant String(void);

"parse error 'void'"
"prototype for "String::String()" does not match any in Class String
"candidates are : "String::String(const String&)"
"String::String(char *)"
"String::String(double)"

etc... */

Alors, une idée de génie pour remédier à ça ? moi , je vois pas :|

Genda67, à votre service !
0
Gendal67 Messages postés 627 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 24 juillet 2011 2
30 oct. 2004 à 18:07
Merci !!!!! Sa marche enfin !!!!!! :-)))))
Untres tres grand merci d'avoir pris le tps de me répondre!!! :))

Gendal67, à votre service !
0
Gendal67 Messages postés 627 Date d'inscription mercredi 16 juin 2004 Statut Membre Dernière intervention 24 juillet 2011 2
30 oct. 2004 à 18:24
Par contre, meme si tout marche, je constate que mon exe obtenu à une taille excessive!!! c comme si il avé absorbé la taille de la dll !! je croyais ke c tpr alléger un prog une dll, nan ?

Gendal67, à votre service !
0
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
30 oct. 2004 à 18:35
Si tu veux lier ta DLL de manière statique, comme le dit cosmobob, il n'y a aucun problème pour accéder à ta classe. Je n'ai jamais travaillé sur DEV C++, mais je pense que tu dois mettre les fichiers "maDLL.h" et "maDLL.lib" dans ton projet comme on le fait avec Visual C++. Ces deux fichiers sont crées dans le projet de création de la DLL:
#include "maDLL.h"
Tu ajoutes également "maDLL.lib" à ton projet client. Ca doit aussi facile avec DEV C++.
Dans ton code client, tu appelleras les fonctions de la DLL directement:
ma_function(int a, int b);

Le problème avec cette méthode (statique), c'est que la classe de ta DLL ne sera accessible ni avec le chargement dynamique, ni avec d'autres compilateurs, ni avec d'autres langages. Si ce n'est pas ton cas, tant mieux. C'est pour cela qu'une fonction d'instanciation de la classe (Interface) est préférable. Cela est dû au fait que les DLL ne connaissent que du "C" pas de "C++". C'est plus compliqué mais quand c'est indispensable, on n'a pas le choix.
Bonne programmation.
0
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
30 oct. 2004 à 18:49
En fait, avec les DLL, il y'a des termes qui se ressemblent mais qui sont très différents. Ce qui prete à confusion parfois. Une DLL statique est en fait ajouté au code éxécutable. Le linkage statique quant à lui, signifie que c'est le système qui s'occupe du chargement de la DLL. Je pense que tu as fait les 2.
0
Rejoignez-nous