OVH Cloud OVH Cloud

utilisation d'une DLL

20 réponses
Avatar
daniel
Bonjour,

Comment utiliser une DLL dans un programme C

Merci

10 réponses

1 2
Avatar
James Kanze
"Pierre Maurette" <mmaauurreettttttee.ppiieerrrree@@ffrreeee.ffrr> writes:

|> a écrit ...
|> > "Pierre Maurette" <mmaauurreettttttee.ppiieerrrree@@ffrreeee.ffrr> wrote

|> > > Ça, c'est le chargement explicite. Vous pouvez utiliser une
|> > > méthode implicite, celle utilisée pour les fonctions des
|> > > API Windows. Dans ce cas, c'est Windows qui se démerde pour
|> > > charger la DLL si nécessaire.

|> > En général, quelque soit le système, il y a plusieurs
|> > façons d'utiliser des objets dynamiques. Une discussion
|> > aprofondie sur les fonctions de l'API et les commandes de
|> > l'éditeur de liens n'a pas sa place ici --

|> Tout à fait d'accord, à part l'idée générale de bib
|> dynamique ( = fichiers image, en gros), les spécificités
|> nombreuses dont il est question sont 100% dépendantes de l'OS.

Un petit détail -- malgré le nom que lui donne Windows, je ne
connais pas de système qui offre réelement les bibliothèques
dynamiques. Quand tu les charges, c'est du tout ou rien. C'est donc un
fichier objet, et non une bibliothèque. (En revanche, si la partage
en était la motivation au départ, aujourd'hui, c'est vraiment
l'aspect dynamique qui prime, et le nom « shared object » qu'on
lui donne sous Unix ne convient plus tout à fait non plus.)

|> De plus, sous Windows, c'est à la base du C et non du C++.

Que ce soit Windows ou Unix, la API est spécifiée en termes de C.
(En fait, sous Unix, elle est spécifiée dans quelque chose qui
n'est pas vraiment du C non plus, vue qu'elle exige des converisions
entre des pointeurs à des données et des pointeurs à des
fonctions, ce qui n'est permis ni en C ni en C++.) Ce n'est pas pour
autant qu'on ne peut pas s'en servir en C++ (voire en Ada, en Fortran,
ou en ce qu'on veut).

|> > c'est propre au système d'exploitation. En revanche, avant d'en
|> > arriver là, il faudrait savoir ce qu'il cherche réelement
|> > à faire, parce que ce qu'il faut faire en dépend
|> > étroitement.

|> > En ce qui concerne les objets dynamiques que tu développes
|> > toi-même, au moins d'écire des bibliothèques avec un API
|> > importante (systèmes d'exploitation, bases de données,
|> > bibliothèques graphiques, etc.), à peu près la seule
|> > raison que je vois pour utiliser le chargement dynamique,

|> Certaines fonctionalités pas si rares que ça imposent sous
|> Windows de transmettre une fonction écrite dans une DLL (filtrage
|> global E/S par exemple, voir SetWindowsHookEx).

Il est aussi assez traditionnel de se servir d'un objet dynamique pour
libc sous Unix. Et alors ? On peut arguementer que c'est en fait ce
qu'on veut -- on veut la version de libc qui correspond à la version
de l'OS qui tourne sur la machine, et non celui qui tournait sur la
machine où on a fait l'édition de liens.

|> > c'est qu'on veut pouvoir choisir entre plusieurs bibliothèques
|> > lors de l'execution, pour que le comportement réel dépend de
|> > l'environement, les paramètres de la ligne de commande, les
|> > droits de l'utilisateur, etc. Ce qui suppose un chargement
|> > explicit de la bibliothèque.

|> Oui. Attention toutefois à ne pas faire le parallèle explicit
|> = usage mono-application et implicit = usage multi-application.

Pas du tout. J'imagine que dans le cas d'une bibliothèque graphique
sous Unix, on se servirait de la bibliothèque dans beaucoup de
programmes, mais la version exacte qu'on charge dépendrait de
l'environement, ou de la ligne de commande.

|> Par exemple, les DLL chargées en implicit peuvent très bien
|> être installées dans le répertoire de l'exécutable, et
|> elles ne polluent pas plus le système.

Et dans ce cas-là, pourquoi utiliser un objet dynamique.

En revanche, je vois bien une application qui charge implicitement la
bibliothèque de l'interface avec la base de données, et qui charge
la bibliothèque Oracle 7 ou celle d'Oracle 8, selon le chemin
précisé par l'utilisateur ($LD_LIBRARY_PATH sous Unix).

|> Sauf si l'on a de bonnes raisons de ne pas charger toutes les DLL
|> d'une appli lors de son lancement. En explicit, on peut opter pour
|> un fonctionnement alternatif/dégradé, en cas d'absence d'un
|> fichier DLL. D'après la doc Microsoft, c'est plutôt implicit
|> qui devrait être choisi par défaut. Personellement, je pense
|> que si l'on est amené à programmer sous Windows, il ne peut
|> être nuisible de programmer une paire de DLL, pour mieux
|> maîtriser le sujet omniprésent.

Qu'on le fasse une fois pour des raisons d'apprentissage, je veux bien.
Qu'on livre une application sauscissonnée en dix DLL qui ne servent
qu'à cette application, je me démande bien pourquoi. En fin de
compte, la seule chose qu'apportent les DLL dans ce cas-là, c'est la
possibilité à l'utilisateur d'avoir un mélange de versions qui
ne fonctionne pas correctement, et que tu ne peux pas dupliqué chez
toi.

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
Avatar
Pierre Maurette
"James Kanze" a écrit ..
Loïc Joly writes:

|> wrote:
|> > En ce qui concerne les objets dynamiques que tu développes
|> > toi-même, au moins d'écire des bibliothèques avec un API
|> > importante (systèmes d'exploitation, bases de données,
|> > bibliothèques graphiques, etc.), à peu près la seule
|> > raison que je vois pour utiliser le chargement dynamique, c'est
|> > qu'on veut pouvoir choisir entre plusieurs bibliothèques lors
|> > de l'execution, pour que le comportement réel dépend de
|> > l'environement, les paramètres de la ligne de commande, les
|> > droits de l'utilisateur, etc. Ce qui suppose un chargement
|> > explicit de la bibliothèque.

|> D'autres utilisations existent :

|> Pouvoir modifier le programme sans l'arrêter (dynamique)

C-à-d que je veux avoir accès à la version la plus récente
disponible dans l'environnement, c-à-d que je veux que la
bibliothèque chargée dépend de l'environnement.

|> Profiter d'une standardisation des bibliothèques dynamiques sur
|> un OS pour faire des programmes multi-langages (statique)

??
Sans doute s'agit-il de "langage" au sens de la localisation des

applications.
Les DLL de ressources de localisation permettent de gérér ce point
facilement (enfin, élégamment) : re-chargement différé (changement de langue
en cours d'utilisation du programme). Il est possible (mais ce n'est pas
spécifiques aux DLL) de "sortir" un module de localisation de l'application
qui peut être mis à la disposition de tiers. Je ne sais plus trop ce qui est
Windows et ce qui est spécifique à Borland dans cette technologie.
Pierre

Avatar
Loïc Joly
James Kanze wrote:
Loïc Joly writes:

|> wrote:
|> > En ce qui concerne les objets dynamiques que tu développes
|> > toi-même, au moins d'écire des bibliothèques avec un API
|> > importante (systèmes d'exploitation, bases de données,
|> > bibliothèques graphiques, etc.), à peu près la seule
|> > raison que je vois pour utiliser le chargement dynamique, c'est
|> > qu'on veut pouvoir choisir entre plusieurs bibliothèques lors
|> > de l'execution, pour que le comportement réel dépend de
|> > l'environement, les paramètres de la ligne de commande, les
|> > droits de l'utilisateur, etc. Ce qui suppose un chargement
|> > explicit de la bibliothèque.

|> D'autres utilisations existent :

[...]


|> Profiter d'une standardisation des bibliothèques dynamiques sur
|> un OS pour faire des programmes multi-langages (statique)

??
Par exemple, windows fourni une spécification de ses DLL qui permet à

tous langages de les utiliser, comme une sorte d'ABI. Cette
spécification est un standard de fait sous windows, et permet donc
d'interfacer deux langages de programmation qui ne savent même pas que
l'autre existe. Dans .NET, cette ABI comprend aussi des notions objet,
ce qui permet à un programme en C++ de dériver d'une classe écrite en
visual basic.

|> Travailler à plusieur entreprises sur un projet sans qu'une seule
|> soit un point de passage obligé pour de la recompilation
|> (statique)

??


Par exemple, une entreprise client A veut un produit qui a besoin de
connaissances de l'entreprise B et C. Plutôt que de demander à B
d'intégrer une bibliothèque classique fournie par C, B et C se mettent
d'accord sur un protocole d'échangepar DLL, et B et C peuvent livrer
indépendamment leur part à A qui se chargera de faire l'intégration.
Inconvénient : A doit savoir ce qu'il fait, avantage : Beaucoup plus de
réactivité, confidentialité accrue.

Avatar
adebaene
James Kanze wrote in message news:...

|> Certaines fonctionalités pas si rares que ça imposent sous
|> Windows de transmettre une fonction écrite dans une DLL (filtrage
|> global E/S par exemple, voir SetWindowsHookEx).

Il est aussi assez traditionnel de se servir d'un objet dynamique pour
libc sous Unix. Et alors ? On peut arguementer que c'est en fait ce
qu'on veut -- on veut la version de libc qui correspond à la version
de l'OS qui tourne sur la machine, et non celui qui tournait sur la
machine où on a fait l'édition de liens.


Pierre parlait d'une fonctionnalité différente : D'une manière
générale, les DLLS permettent "d'injecter" dynamiquement son code dans
une application tierce, ce qui peut être utiles pour certaines
opérations : instrumentation, log, ceraint mécanismes utilisés par les
antivirus, et malheureusement d'autre activités moins honnêtes. Mais
bon, on est très loin du C++ là!

Qu'on le fasse une fois pour des raisons d'apprentissage, je veux bien.
Qu'on livre une application sauscissonnée en dix DLL qui ne servent
qu'à cette application, je me démande bien pourquoi. En fin de
compte, la seule chose qu'apportent les DLL dans ce cas-là, c'est la
possibilité à l'utilisateur d'avoir un mélange de versions qui
ne fonctionne pas correctement, et que tu ne peux pas dupliqué chez
toi.


C'est vrai. Ceci dit, sur des systèmes complexes, les librairies
dynamiques peuvent simplifier le déploiement et la mise à jour
(patchs), avec évidemment les risques de mélange de versions que cela
implique.
A noter que .NET offre un mécanisme intéressant de ce point de vue :
Par défaut (c'est modifiable par fichier de configuration), un
executable n'accepte de fonctionner qu'avec les DLL exactes contre
lesquelles il a été construit (numéro de version, CRC et
éventuellement signature).

Arnaud

Avatar
kanze
(Arnaud Debaene) wrote in message
news:...
James Kanze wrote in message
news:...


[...]
Qu'on le fasse une fois pour des raisons d'apprentissage, je veux
bien. Qu'on livre une application sauscissonnée en dix DLL qui ne
servent qu'à cette application, je me démande bien pourquoi. En fin
de compte, la seule chose qu'apportent les DLL dans ce cas-là, c'est
la possibilité à l'utilisateur d'avoir un mélange de versions qui ne
fonctionne pas correctement, et que tu ne peux pas dupliqué chez
toi.


C'est vrai. Ceci dit, sur des systèmes complexes, les librairies
dynamiques peuvent simplifier le déploiement et la mise à jour
(patchs), avec évidemment les risques de mélange de versions que cela
implique.


Dans le cas des systèmes complexes, où il y a plusieurs processus, il
faut bien faire un analyse de ce qu'on veut avoir dans une bibliothèque,
et ce qu'on ne veut pas. Dès qu'on peut raisonablement s'attendre à ce
que la bibliothèque sert à plusieurs processus, la question se pose. Ce
qui ne veut pas dire que la bonne réponse est toujours l'utilisation des
objets dynamiques, mais simplement que c'est une solution qu'on ne peut
pas écarter d'office.

A noter que .NET offre un mécanisme intéressant de ce point de vue :
Par défaut (c'est modifiable par fichier de configuration), un
executable n'accepte de fonctionner qu'avec les DLL exactes contre
lesquelles il a été construit (numéro de version, CRC et
éventuellement signature).


Il y a quelque chose de semblable sous Unix, ou au moins sous Solaris.
Mais pour qu'il fonctionne, il faut qu'il y a une bonne gestion des
versions -- en fin de compte, c'est bien le programmeur qui determine,
explicitement ou implicitement, le numéro de version de la bibliothèque.
Et j'en ai vu plus d'une fois où le programmeur a décidé à ne pas
incrémenter la version après une modification.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16


Avatar
Arnaud Debaene
wrote:

A noter que .NET offre un mécanisme intéressant de ce point de vue :
Par défaut (c'est modifiable par fichier de configuration), un
executable n'accepte de fonctionner qu'avec les DLL exactes contre
lesquelles il a été construit (numéro de version, CRC et
éventuellement signature).


Il y a quelque chose de semblable sous Unix, ou au moins sous Solaris.
Mais pour qu'il fonctionne, il faut qu'il y a une bonne gestion des
versions -- en fin de compte, c'est bien le programmeur qui determine,
explicitement ou implicitement, le numéro de version de la
bibliothèque. Et j'en ai vu plus d'une fois où le programmeur a
décidé à ne pas incrémenter la version après une modification.


.NET utilise le CRC du module, ce qui évite ce genre "d'oublis".

Arnaud


Avatar
Jean-Marc Bourguet
"Arnaud Debaene" writes:

wrote:

A noter que .NET offre un mécanisme intéressant de ce point de vue :
Par défaut (c'est modifiable par fichier de configuration), un
executable n'accepte de fonctionner qu'avec les DLL exactes contre
lesquelles il a été construit (numéro de version, CRC et
éventuellement signature).


Il y a quelque chose de semblable sous Unix, ou au moins sous Solaris.
Mais pour qu'il fonctionne, il faut qu'il y a une bonne gestion des
versions -- en fin de compte, c'est bien le programmeur qui determine,
explicitement ou implicitement, le numéro de version de la
bibliothèque. Et j'en ai vu plus d'une fois où le programmeur a
décidé à ne pas incrémenter la version après une modification.


.NET utilise le CRC du module, ce qui évite ce genre "d'oublis".


Vu que pour moi la version est une affaire de semantique, je ne vois
pas comment un CRC peut verifier la semantique. Meme si on se
contente d'un CRC sur l'interface, il faut etre plus sioux parce qu'on
peut fournir une bibliotheque qui a une interface plus etendue.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org



Avatar
James Kanze
Jean-Marc Bourguet writes:

|> "Arnaud Debaene" writes:

|> > wrote:

|> > >> A noter que .NET offre un mécanisme intéressant de ce
|> > >> point de vue : Par défaut (c'est modifiable par fichier de
|> > >> configuration), un executable n'accepte de fonctionner qu'avec
|> > >> les DLL exactes contre lesquelles il a été construit
|> > >> (numéro de version, CRC et éventuellement signature).

|> > > Il y a quelque chose de semblable sous Unix, ou au moins sous
|> > > Solaris. Mais pour qu'il fonctionne, il faut qu'il y a une bonne
|> > > gestion des versions -- en fin de compte, c'est bien le
|> > > programmeur qui determine, explicitement ou implicitement, le
|> > > numéro de version de la bibliothèque. Et j'en ai vu plus
|> > > d'une fois où le programmeur a décidé à ne pas
|> > > incrémenter la version après une modification.

|> > .NET utilise le CRC du module, ce qui évite ce genre
|> > "d'oublis".

|> Vu que pour moi la version est une affaire de semantique, je ne vois
|> pas comment un CRC peut verifier la semantique. Meme si on se
|> contente d'un CRC sur l'interface, il faut etre plus sioux parce
|> qu'on peut fournir une bibliotheque qui a une interface plus
|> etendue.

Je ne connais pas le .net, mais au moins en C++ classique, un CRC sur
des définitions de classe pourrait être bien utile.

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
Avatar
Jean-Marc Bourguet
James Kanze writes:

Jean-Marc Bourguet writes:

|> "Arnaud Debaene" writes:

|> > wrote:

|> > >> A noter que .NET offre un mécanisme intéressant de ce
|> > >> point de vue : Par défaut (c'est modifiable par fichier de
|> > >> configuration), un executable n'accepte de fonctionner qu'avec
|> > >> les DLL exactes contre lesquelles il a été construit
|> > >> (numéro de version, CRC et éventuellement signature).

|> > > Il y a quelque chose de semblable sous Unix, ou au moins sous
|> > > Solaris. Mais pour qu'il fonctionne, il faut qu'il y a une bonne
|> > > gestion des versions -- en fin de compte, c'est bien le
|> > > programmeur qui determine, explicitement ou implicitement, le
|> > > numéro de version de la bibliothèque. Et j'en ai vu plus
|> > > d'une fois où le programmeur a décidé à ne pas
|> > > incrémenter la version après une modification.

|> > .NET utilise le CRC du module, ce qui évite ce genre
|> > "d'oublis".

|> Vu que pour moi la version est une affaire de semantique, je ne
|> vois pas comment un CRC peut verifier la semantique. Meme si on
|> se contente d'un CRC sur l'interface, il faut etre plus sioux
|> parce qu'on peut fournir une bibliotheque qui a une interface
|> plus etendue.

Je ne connais pas le .net, mais au moins en C++ classique, un CRC
sur des définitions de classe pourrait être bien utile.


D'accord, c'est ce que j'appelai un CRC sur l'interface (je ne sais
pas si ce mot a un sens precis en C#, en tout cas je l'employais dans
le sens general). Et meme alors, le CRC m'empechera de fournir une
nouvelle version parce que j'ai ajoute une fonction membre privee non
virtuelle... je sais c'est une violation de la ODR, mais dans le cadre
de bibliotheque dynamique c'est utile. Meme un membre public devrait
pouvoir etre ajoute dans ce cas. Mais on a aussi parfois le desir de
vouloir changer le CRC, parce qu'on a change la semantique sans que
rien ne le dise dans l'interface.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
James Kanze
Jean-Marc Bourguet writes:

|> James Kanze writes:

[...]
|> > Je ne connais pas le .net, mais au moins en C++ classique, un CRC
|> > sur des définitions de classe pourrait être bien utile.

|> D'accord, c'est ce que j'appelai un CRC sur l'interface (je ne sais
|> pas si ce mot a un sens precis en C#, en tout cas je l'employais
|> dans le sens general).

Je y pensais dans le contexte du C++, avec l'idée de l'appliquer à
tout ce qui tombe sur la ODR.

|> Et meme alors, le CRC m'empechera de fournir une nouvelle version
|> parce que j'ai ajoute une fonction membre privee non virtuelle...

Ce qui est formellement intérdit. Personellement, il nous aurait
sauver pas mal de temps plusieurs fois dans la passée, où
quelqu'un avais ajouté une variable membre privée:-).

En fait, c'est à celui qui l'implémente de choisir ce qu'il y met.
La plus facile, c'est simplement le texte de la définition en
question. Mais c'est trop et pas assez à la fois. Trop, parce que
même un changement dans un commentaire... Et pas assez, parce que si
la définition utilise un typedef qui est défini ailleurs...

Mais ç'aurait déjà été mieux que rien.

|> je sais c'est une violation de la ODR, mais dans le cadre de
|> bibliotheque dynamique c'est utile. Meme un membre public devrait
|> pouvoir etre ajoute dans ce cas. Mais on a aussi parfois le desir de
|> vouloir changer le CRC, parce qu'on a change la semantique sans que
|> rien ne le dise dans l'interface.

J'offre une main, et il veut le bras:-).

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
1 2