Utilisation DLL dynamique / getprocAddress null

Signaler
Messages postés
21
Date d'inscription
mardi 11 août 2009
Statut
Membre
Dernière intervention
20 juin 2011
-
Messages postés
21
Date d'inscription
mardi 11 août 2009
Statut
Membre
Dernière intervention
20 juin 2011
-
Bonjour à tous !

J'essaye d'utiliser une DLL fournie sans .lib, mais avec un beau .h, du coup je tente la combo LoadLibrary et GetProcAddress. Le problème c'est que GetProcAddress me renvoi NULL tout le temps.

Je suis sous windows (XP 64 bits) et je développe avec VS 2008 (que je maîtrise mal).

Vla mon code :
Ma dll s'appelle MADLL.dll et son header associé MADLL.h.
Les fonctions dans le header de la DLL sont déclarées en extern "C" :

MADLL.H

extern "C"
{
    __declspec(dllexport) MonTypeDeRetour __stdcall MADLL_MaFonction();

    ...
}


MAIN.H

#include ;
#include <stdio.h>
#include <windows.h>

#include "MADLL.h"

...


MAIN.CPP

#include "main.h"

using namespace std;

int main()
{

typedef UINT (__stdcall* MYDLLFUNC)(DWORD,UINT);
HINSTANCE hDLL;
MYDLLFUNC ImpFuncDLL;

hDLL = LoadLibrary(L"MADLL");
if (hDLL != NULL)
{
ImpFuncDLL = (MYDLLFUNC)GetProcAddress(hDLL, "MADLL_MaFonction");

if (!ImpFuncDLL)
{
cout<<"error"<<endl;
        FreeLibrary(hDLL);       
        return 1;
}
else
                ...


L’exécution m'affiche toujours 'error', donc GetProcAddress renvoie NULL.

J'ai pas mal tourné sur le net pour trouver une réponse mais je bloque toujours...

La DLL se load puisqu'on rentre dans le if, donc je vais mal chercher les fonctions... Est-ce qu'il faut que je colle un __declspec(dllimport) quelque part ?

Help !

Merci :)
A voir également:

20 réponses

Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
24
Controle deja avec depends.exe (dispo sur le net) que la DLL exporte bien ta fonction.

ciao...
BruNews, MVP VC++
Messages postés
21
Date d'inscription
mardi 11 août 2009
Statut
Membre
Dernière intervention
20 juin 2011

WoW !

ça c'est de l'aide qui poutre.

En effet les noms des fonctions sont suivis d'un "@X", X étant un nombre.

Merci beaucoup BruNews !

Pour info, ça vient d'où cet @ ?
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
24
X est le nombre d'octets des parametres, jusque là donc tout va bon.

ciao...
BruNews, MVP VC++
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
24
Attention aussi, tu mets que h precise que dll exporte:
MonTypeDeRetour __stdcall MADLL_MaFonction();
0 param.

mais dans ton code on voit:
typedef UINT (__stdcall* MYDLLFUNC)(DWORD,UINT);.
avec 2 params !!!

ciao...
BruNews, MVP VC++
Messages postés
21
Date d'inscription
mardi 11 août 2009
Statut
Membre
Dernière intervention
20 juin 2011

Yep yep, j'avais pas complété les paramètres de MADLL_MaFonction

Encore merci
Messages postés
21
Date d'inscription
mardi 11 août 2009
Statut
Membre
Dernière intervention
20 juin 2011

Fausse joie. Il s'avère que ça ne résout pas mon problème.

MAIN.CPP

#include "main.h"

using namespace std;

int main()
{

typedef int (__stdcall* MYDLLFUNC)(const char*);
        HINSTANCE hDLL;
MYDLLFUNC ImpFuncDLL;
int res;

hDLL = LoadLibrary(L"MADLL");
if (hDLL != NULL)
{

ImpFuncDLL = (MYDLLFUNC)GetProcAddress(hDLL,
"Mafonction@4");
if (!ImpFuncDLL)
{
cout<<"error"<<endl;
        FreeLibrary(hDLL);       
        return 1;
}
else
{
                res = ImpFuncDLL("blob");
        FreeLibrary(hDLL);
                        return 0;
}
}
}


Avec
MADLL.H

extern "C"
{
    __declspec(dllexport) int __stdcall MaFonction(const char* name);
    ...
}



Et ça m'affiche error...
Messages postés
21
Date d'inscription
mardi 11 août 2009
Statut
Membre
Dernière intervention
20 juin 2011

Il faut lire : ImpFuncDLL = (MYDLLFUNC)GetProcAddress(hDLL, "MaFonction@4");
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
24
_MaFonction@4
est le nom "décoré" standard, à GetProcAddress() c'est le nom SANS déco qu'on passe, 'MaFonction' ici.

ciao...
BruNews, MVP VC++
Messages postés
21
Date d'inscription
mardi 11 août 2009
Statut
Membre
Dernière intervention
20 juin 2011

Bah c'est ce que je faisais avant (voir mon 1° post).

Du coup c'est pas ça le problème. Je sèche toujours...

Une autre idée ?
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
24
Si tu peux mettre sur un serveur un zip contenant la dll et fichier h, je testerai ce soir.

ciao...
BruNews, MVP VC++
Messages postés
21
Date d'inscription
mardi 11 août 2009
Statut
Membre
Dernière intervention
20 juin 2011

Malheureusement non je ne peux pas. Mais merci de proposer.
Messages postés
21
Date d'inscription
mardi 11 août 2009
Statut
Membre
Dernière intervention
20 juin 2011

Apparemment, je n'arrive pas à accéder du tout à la DLL, bien que le LoadLibrary soit fait.

En effet :

MADLL.H

using namespace std;

struct TestStruct;
...


MAIN.CPP

int main()
{
        HINSTANCE hDLL;
hDLL = LoadLibrary(L"MADLL");
if (hDLL != NULL)
{
     		TestStruct testStruct;
        }
}


Donne comme message d'erreur :
error C2079: 'testStruct' uses undefined struct 'TestStruct'

C'est-à-dire, si je comprends bien, que le compilo sait que TestStruct est une struct grâce au DLL.h, qu'il charge bien la DLL, mais qu'il n'arrive pas à y accéder...

Je ne vois pas d'explication.
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
salut,

Comme l'origine du problème peut être divers et varié, utilise la fonction GetLastError. Tu sauras plus précisement d'où vient le problème.

Dans un premier temps, met LoadLibrary("MADLL.DLL") pour voir. Assures-toi que la DLL soit dans un des repertoires de recherche par defaut.

@++
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
re,

"C'est-à-dire, si je comprends bien, que le compilo sait que TestStruct est une struct grâce au DLL.h, qu'il charge bien la DLL, mais qu'il n'arrive pas à y accéder..."

Absolument pas, ça veut dire que ton programme ne compile pas car le compilo ne connaît pas la composition de la structure. Le type existe mais il ne correspond à rien.

@++
Messages postés
21
Date d'inscription
mardi 11 août 2009
Statut
Membre
Dernière intervention
20 juin 2011

Salut Patatalo.

Je ferai le test de GetLastError demain, merci pour l'info.

Quant à LoadLibrary("MADLL.DLL"), j'ai déjà essayé, et ça ne change rien. (La DLL est dans le répertoire courant).

Quand je dis qu'il charge bien la DLL, c'est que si je change le nom du fichier (par exemple MADL.DLL) le programme passe dans la boucle du (hDLL == NULL)...
Messages postés
21
Date d'inscription
mardi 11 août 2009
Statut
Membre
Dernière intervention
20 juin 2011

En ce qui concerne GetLastError ça me donne 0 même après
HMODULE hDLL = LoadLibrary(L"SE-Brain_Release.DLL");

puis 127 après
ImpFuncDLL = (MYDLLFUNC)GetProcAddress(hDLL,
"SEBrain_Sync_playTests");


127 c'est "The specified procedure could not be found" si je ne m'abuse. Et un google rapide ne m'éclaire pas beaucoup plus...
Messages postés
21
Date d'inscription
mardi 11 août 2009
Statut
Membre
Dernière intervention
20 juin 2011

Pour info, Dependency Walker me donne un message d'erreur sur ma DLL :

Error: At least one required implicit or forwarded dependency was not found.
Warning: At least one delay-load dependency module was not found.

(peut-être que ça a un quelconque rapport)

Donc je ne comprends toujours pas d'où vient le problème... Problème de compatibilité avec mon XP 64 bits ?
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
salut,


Le problème est que ta fonction ne doit pas être déclarée comme exportée. Tu as certainement oublié le fichier .def quand tu as compilé ta dll.

@++
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
11
Salut,

La fonction est déclarée comme exportée car il a utilisé __declspec(dllexport). Depends confirme cet export, mais décoré.

Il faudrait exporter la fonction de manière non décorée.

Pour ne pas avoir de décoration, il faut en effet passer par un fichier .def.

Enlève le __declspec(dllexport) et passe par un .def.
Messages postés
21
Date d'inscription
mardi 11 août 2009
Statut
Membre
Dernière intervention
20 juin 2011

Yep

Ok, je vais regarder ça.

Merci !