OVH Cloud OVH Cloud

LoadLibrary et GetProcAddress

40 réponses
Avatar
PurL
Bonjour,

Comment, dans un programme, peut-on utiliser les fonctions LoadLibrary et
GetProcAddress (faisant parties de l'API windows), sans inclure le .h
correspondant ?

PurL

10 réponses

1 2 3 4
Avatar
AMcD
Fabien SK wrote:

D'ailleurs (tiens, on commence à couper les cheveux en quatre), si je
dis: - "dépendance statique" et "dépendance dynamique", ça correspond
bien à
ce que je veux dire
- "link statique" et "link dynamique", c'est pas bon.



Heu, j'ai du mal à suivre l'intérêt de cette nébuleuse discussion.

- le code est inscrit dans ton appli : c'est du statique.
- le code est chargé implicitement à l'exécution : c'est du dynamique.
- le code est chargé explicitement à l'exécution (GetProcAddress()) : c'est
pseudo-dynamique, puisque le linker n'a pas fait grand-chose vis-à-vis des
fonctions chargées par GetprocAddress()..

Faut pas confondre link/dépendance, implicite/explicite et
statique/dynamique.

--
AMcD

http://arnold.mcdonald.free.fr/
Avatar
Vincent Burel
"Fabien SK" <fabsk+ wrote in message
news:3f8d0072$0$27605$
>>Comment nommes-tu le fait d'utiliser une DLL:
Préambule: son problème était d'accéder aux fonctions "LoadLibrary" et
"GetProcAddress" (ça aurait pu être "CreateWindow", le problème aurait
été le même).

Ca tombe bien, ma première réponse à PurL était:

--- citation ---
Moi: Le .h n'est pas important. Tu peux réécrire le prototype dans ton
code. C'est le .lib qu'il te faut, ce qu'il va faire que ton .exe ou ta
.dll va dépendre statiquement de kernel32.dll
---

Note que je n'ai pas écrit "linker statiquement kernel32.dll".
Ce à quoi tu me réponds:

--- citation ---
Toi: s'il utilise LoadLibrary et GetProcAddress , il n'a pas besoin du


.LIB
[je passe la partie où tu m'expliques ce qu'est une DLL, un .LIB et un


link]

je n'avais pas compris la question comme il faut. J'ai cru qu'il voulait
utiliser une librairy avec LoadLibrary et GetProcAddress... d'ailleurs j'ai
toujours du mal à comprendre car je ne vois pas bien comment on peut faire
un LoadLibrary sur Kernel32 sans que cette même Kernel32 soit linkée...

Vu qu'il veut accéder à la fonction "LoadLibrary", il a besoin de
kernel.lib (tu n'avais pas compris son problème). Donc j'essaye de
reexpliquer tout ça:

--- citation ---
Moi: "kernel32.lib" _fait_ que le programme va dépendre statiquement de
"kernel32.dll".
Je ne connais pas d'autre moyen d'utiliser "LoadLibrary" que de linker
statiquement avec "kernel32.dll".
---

OK, j'ai dit "linker statiquement". Mais tout de même, je t'ai parlé
deux fois de dépendance statique au dessus.



oui, on se bataille sur un problème de forme sans intérêt... Faut dire que
ce thread est plus que nébuleux... D'ailleurs maintenant je n'y comprend
plus rien :-)

Vincent Burel
Avatar
PurL
> oui, on se bataille sur un problème de forme sans intérêt... Faut
dire que ce thread est plus que nébuleux... D'ailleurs maintenant je
n'y comprend plus rien :-)



Oui effectivement, vous etes parti dans des discours... :)

Voir plus bas mon post à Arnaud Debaene pour une explication un peu plus
clair...

Merci, pour votre contribution...

PurL.
Avatar
Vincent Burel
"PurL" wrote in message
news:bmj6t6$bi5$
> A moins que tes DLLs plugins aient besoin d'appeler LoadLibray, il n'y
> a pas de problèmes, ou alors j'ai rien comris à ce que tu veux
> faire....
>
> Arnaud


Je vais essayer de réexpliquer :

Mon programme manipule des données d'acquisition.
L'utilisateur peut ecrire du code CPP pour "jouer" avec ces données (comme
les macro sous excel)
De plus, l'utilisateur peut avoir accès à des dll contenant des fonctions
(que j'appelle DLL bibliothèque) (j'en ai fait une par exemple pour les
fonctions mathèmatiques COS, SIN, ...)
Quand l'utilisateur à écrit son code, le programme compile ce code pour
créer une DLL (que j'ai appellé DLL charnière) capable d'appeler les DLL
bibliothèque (dans l'exemple celle qui contient les fonctions
mathématiques).
Donc les DLL bibliothèque sont effectivement créées sur mon poste donc là,
pas de probleme mais la DLL charniere c'est le programme principale qui la
créer sur le poste de l'utilisateur. Et cette DLL charnière à besoin de
LoadLibrary / GetProcAddress / FreeLibrary pour appeler les fonctions des
DLL bibliothèques.



Je comprends le but que vous voulez atteindre, je ne comprends pas la
méthode. Car enfin si vous voulez fournir des fonction à votre DLL
utilisateur (le plug-in), vous pouvez tout aussi bien lui fournir à
l'initialisation, une table de vecteur (qui correspondent à des fonctions
qui se trouvent ou dans votre programme principale, ou dans un DLL linké à
votre programme principale)... Toutes les DLL d'un Process sont dans le même
espace d'adressage, un Host à le droit de prendre un pointeur de fonction
dans la DLL A pour le filer à la DLL B.

C'est en ce sens que je ne vois même pas pourquoi votre DLL client aurait
besoin de LoadLibrary. Au pire vous pourrier linker le code de votre client
avec un DLL compilé qui s'occuperait de faire ces chargement de library...

Vincent Burel
Avatar
PurL
> Je comprends le but que vous voulez atteindre, je ne comprends pas la
méthode. Car enfin si vous voulez fournir des fonction à votre DLL
utilisateur (le plug-in), vous pouvez tout aussi bien lui fournir à
l'initialisation, une table de vecteur (qui correspondent à des
fonctions qui se trouvent ou dans votre programme principale, ou dans
un DLL linké à votre programme principale)... Toutes les DLL d'un
Process sont dans le même espace d'adressage, un Host à le droit de
prendre un pointeur de fonction dans la DLL A pour le filer à la DLL
B.



Je ne suis pas expert de linkage :(
Je peux compiler qqch faisant appel à des fonctions de DLL tiers en ayant
uniquement un .h et un .dll ? comment ?
Pour info j'utilise le linker de borland : ilink32.exe

Vincent Burel



PurL
Avatar
Vincent Burel
"PurL" wrote in message
news:bmjhdd$ack$
> Je comprends le but que vous voulez atteindre, je ne comprends pas la
> méthode. Car enfin si vous voulez fournir des fonction à votre DLL
> utilisateur (le plug-in), vous pouvez tout aussi bien lui fournir à
> l'initialisation, une table de vecteur (qui correspondent à des
> fonctions qui se trouvent ou dans votre programme principale, ou dans
> un DLL linké à votre programme principale)... Toutes les DLL d'un
> Process sont dans le même espace d'adressage, un Host à le droit de
> prendre un pointeur de fonction dans la DLL A pour le filer à la DLL
> B.

Je ne suis pas expert de linkage :(
Je peux compiler qqch faisant appel à des fonctions de DLL tiers en ayant
uniquement un .h et un .dll ? comment ?
Pour info j'utilise le linker de borland : ilink32.exe



avec cette méthode vous n'avez pas besoin du linker.
imaginons que vous voulez fournir cette fonction à votre plug client :

typedef float (*typeCOS)(float a);

bon déjà faut prototyper comme il faut et mettre la convention d'appel.
par exemple.
typedef float (__cdecl *typeCOS)(float a);

ensuite vous déclarez une structure commune (au host et au plug) dans un
header,
qui contient la liste de vos fonctions, appelons cela un service que vous
voulez fournir à votre client (mais en vrai sa s'appelle une interface :-).

typedef struct tagSERVICE_HOST
{
typeCOS Cos;
...
etc...
} T_SERVICE_HOST, * LPT_SERVICE_HOST;

Au niveau du client vous déclarez juste un pointeur
static LPT_SERVICE_HOST service=NULL;

et vous changez cette fonction simplement pour recevoir l'addresse du
service (l'adrese de l'interface).

extern "C" __declspec(dllexport) void __stdcall Init(LPT_SERVICE_HOST lps)
{
service=lps;
}

Une fois cette fonction appelé par le host, "service" contient une adresse
sur le service fourni par le host. le client n'a plus qu'a faire un
service->Cos(...) pour appeler la fonction en question.

ou bien vous définissez une macro qui cache la structure au client pour que
le code soit plus lisible.
#define COS(nnn) service->Cos(nnn)

extern "C" __declspec(dllexport) float __stdcall Calcul0(float *GRD)
{
return COS(GRD[1] * 2); //on utilise une fonction du service.
}


COTE HOST
------------------
avec cette méthode, c'est le host qui charge (ou link les DLL) dont il aura
éventuellement besoin pour fournir sont service... Mais le code des
fonctions du service peut tout aussi bien être dans le source du Host.

Le but étant de definir une variable contenant la liste de vos fonctions à
fournir à votre client.
par exemple
static T_SERVICE_HOST servicefunctionlist {
COS,
SIN,
etc...
};

ou encore,

h0 = LoadLibrary("C:mathmath.dll");
COS = (typeCOS)GetProcAddress(h0, "COS");
servicefunctionlist.cos=COS;

SIN = (typeSIN)GetProcAddress(h0, "SIN");
servicefunctionlist.sin=COS;

etc...

Et après vous pourrez appelez la fonction du plug
Init(&servicefunctionlist);
pour lui fournir un pointeur sur la structure T_SERVICE_HOST que lui comme
vous connaissez et qui contient la liste des fonctions utilisables par le
plug client...

A+
Vincent Burel
Avatar
adebaene
"PurL" wrote in message news:<bmj6t6$bi5$...
> A moins que tes DLLs plugins aient besoin d'appeler LoadLibray, il n'y
> a pas de problèmes, ou alors j'ai rien comris à ce que tu veux
> faire....
>
> Arnaud


Je vais essayer de réexpliquer :

Mon programme manipule des données d'acquisition.
L'utilisateur peut ecrire du code CPP pour "jouer" avec ces données (comme
les macro sous excel)
De plus, l'utilisateur peut avoir accès à des dll contenant des fonctions
(que j'appelle DLL bibliothèque) (j'en ai fait une par exemple pour les
fonctions mathèmatiques COS, SIN, ...)
Quand l'utilisateur à écrit son code, le programme compile ce code pour
créer une DLL (que j'ai appellé DLL charnière) capable d'appeler les DLL
bibliothèque (dans l'exemple celle qui contient les fonctions
mathématiques).
Donc les DLL bibliothèque sont effectivement créées sur mon poste donc là,
pas de probleme mais la DLL charniere c'est le programme principale qui la
créer sur le poste de l'utilisateur. Et cette DLL charnière à besoin de
LoadLibrary / GetProcAddress / FreeLibrary pour appeler les fonctions des
DLL bibliothèques.



Ok. A ce niveau là, est-ce qu'il ne serait pas plus simple et plus
clair que, lors de l'init de ta DLL charnière, ton exe principal lui
passe une table nom de la fonction <--> pointeur vers la fonction qui
te donne les addresses de toutes les fonctions de toutes tes DLL
bilbiothèques, et dans ta fonction d'init tu utilises cette table
plutôt que de faire des GetProcAddress?

Arnaud
Avatar
Cyrille \cns\ Szymanski
> Mon programme manipule des données d'acquisition.
L'utilisateur peut ecrire du code CPP pour "jouer" avec ces données
(comme les macro sous excel)



Ah mais ce qu'il vous faut c'est un langage script. Ils ont l'avantage de
venir avec des interpréteurs intégrés et généralement des wrappers pour le
langage de développement choisi ce qui vous évite de trimballer un
compilateur.

Je ne peux que vous conseiller LUA qui semble parfaitement adapté à ce que
vous cherchez à faire.

http://www.lua.org/

Cordialement,
--
_|_|_| CnS
_|_| for(n=0;b;n++)
_| b&=b-1; /*pp.47 K&R*/
Avatar
PurL
PurL wrote:
Bonjour,

Comment, dans un programme, peut-on utiliser les fonctions
LoadLibrary et GetProcAddress (faisant parties de l'API windows),
sans inclure le .h correspondant ?

PurL



Tout d'abord je vous remercie encore tous pour votre aide.
Finalement, je me suis bien compliqué la vie avec mes histoires de
LoadLibrary/GetProcAddress.

Puisque les .h des DLL bibliopthèques en include dans ma DLL charniere et
les .LIB données aux linker ont suffit à résoudre mon probleme.
Faute de temps, je ne peux me pencher sur les autres solutions proposées
telles que la table de vecteurs ou encore le langage de script.
Mais je garde ces différentes approches sous le coude :)

Je rencontre maintenant d'autres problemes, mais je n'ai pas encore poussé
assez ma recherche pour comprendre le pourquoi.
En tous cas, voici ce que je peux vous dire actuellement :

L'appli est compiler sous BCB5.0 avec options information de debuggage +
surveillance CodeGuard le tout sous Win2000:

quand le prog fait
HINSTANCE hLib = LoadLibrary(maDll);

et tout de suite après,
FreeLibrary(hLib);

Quand je fais autres choses avec l'application (je sais que "autres choses"
c'est imprecis, mais je n'arrive pas à identifier la manip qui fait planté)
CodeGuard me signale une violation d'accès n'importe où, un coup sur la
création d'objet, un coup sur l'accès à la propriété "font" d'un caption.

Je précise que je n'avais pas cette erreur avant.

2 informations :
- C'est le FreeLibrary qui provoque cà, car si je l'enleve, je n'ai aucun pb
de fonctionnement (si ce n'est que ma DLL n'est pas libérer).
- Si je désactive CodeGuard, je n'ai plus l'erreur donc : soit c'est
l'intégration de CodeGuard qui fait désordre auquel cas ce n'est pas mon
prog, soit je n'ai plus d'erreur car je n'ai plus l'outils pour la détecter
mais elle est toujours là (cachée) et un jour fera planté le programme dans
certaines conditions.

A suivre, en tous cas si vous avez un quelconque debut de piste, je suis
preneur :)

Sur ce, bonne journée,

PurL
Avatar
voir
On Wed, 15 Oct 2003 09:16:51 +0200, Fabien SK <fabsk+
wrote:

Comment nommes-tu le fait d'utiliser une DLL:
- en spécifiant au link la liaison entre ton programme et la DLL ?
(chargement de la DLL lors de la création du process par le système)
- en chargeant la DLL avec "LoadLibrary" ? (chargement de la DLL pendant
l'exécution du programme)

Moi je n'ai pas d'autres mots pour dire ça. D'un coté la dépendance est
statique, et de l'autre non. Si tu as une autre manière de dire ça, je
suis preneur.



Ca s'appelle linkage implicite (avec le .lib qui contient les refs
vers la DLL)

statique c'est qd le .lib contient du vrai code linké ds l'appli


=-=-=-=-=-=-=-=-=-=-
Fred
#include "SignatureSympa.h"
/* Mon email c'est sur freesurf.fr et c'est "fr-p" */
1 2 3 4