Problême de DLL [Résolu]

Signaler
Messages postés
627
Date d'inscription
mercredi 16 juin 2004
Statut
Membre
Dernière intervention
24 juillet 2011
-
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
-
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

Messages postés
700
Date d'inscription
mardi 30 décembre 2003
Statut
Membre
Dernière intervention
27 janvier 2009
4
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++ ;)
Messages postés
2865
Date d'inscription
samedi 2 novembre 2002
Statut
Membre
Dernière intervention
11 mai 2009
11
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..."
Messages postés
627
Date d'inscription
mercredi 16 juin 2004
Statut
Membre
Dernière intervention
24 juillet 2011

Oui, mais pas ac les classes (juste les fonctions), ou alors je dois etre aveugle ou mal chercher...

Genda67, à votre service !
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
13
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.
Messages postés
627
Date d'inscription
mercredi 16 juin 2004
Statut
Membre
Dernière intervention
24 juillet 2011

racpp, je t'en prie, tes paroles me plaisent, donne voir un exemple, je te prie!! Tu seras un ange!! ^^

Genda67, à votre service !
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
13
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++.
Messages postés
627
Date d'inscription
mercredi 16 juin 2004
Statut
Membre
Dernière intervention
24 juillet 2011

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 !
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
13
met ton code ici et on verra comment arranger ça
Messages postés
627
Date d'inscription
mercredi 16 juin 2004
Statut
Membre
Dernière intervention
24 juillet 2011

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 !
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
13
Ok, je vais voir comment régler tout ça dès que j'ai un peu de temps.
Messages postés
627
Date d'inscription
mercredi 16 juin 2004
Statut
Membre
Dernière intervention
24 juillet 2011

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 !
Messages postés
700
Date d'inscription
mardi 30 décembre 2003
Statut
Membre
Dernière intervention
27 janvier 2009
4
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++ ;)
Messages postés
627
Date d'inscription
mercredi 16 juin 2004
Statut
Membre
Dernière intervention
24 juillet 2011

Petit probleme : ton __declspec(dllexport) n'est pas le bienvenue chez dev-c++ lorsqu'il est mis devant un constructeur !!

Genda67, à votre service !
Messages postés
627
Date d'inscription
mercredi 16 juin 2004
Statut
Membre
Dernière intervention
24 juillet 2011

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 !
Messages postés
700
Date d'inscription
mardi 30 décembre 2003
Statut
Membre
Dernière intervention
27 janvier 2009
4
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++ ;)
Messages postés
627
Date d'inscription
mercredi 16 juin 2004
Statut
Membre
Dernière intervention
24 juillet 2011

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 !
Messages postés
627
Date d'inscription
mercredi 16 juin 2004
Statut
Membre
Dernière intervention
24 juillet 2011

Merci !!!!! Sa marche enfin !!!!!! :-)))))
Untres tres grand merci d'avoir pris le tps de me répondre!!! :))

Gendal67, à votre service !
Messages postés
627
Date d'inscription
mercredi 16 juin 2004
Statut
Membre
Dernière intervention
24 juillet 2011

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 !
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
13
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.
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
13
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.