OVH Cloud OVH Cloud

Utilité DLL C++

100 réponses
Avatar
Korchkidu
Bonjour,

A partir de quand estimez vous que faire une DLL plutot qu'un LIB soit
int=E9ressant. En effet, utiliser des DLL fait des programmes plus
petits (entre autres) mais induit d'enormes contraintes au niveau de la
programmation. Donc d'apres moi, faire une DLL pour une bibliotheque de
petite taille n'est pas forcement une bonne idee...

Merci pour vos commentaires.
K=2E

10 réponses

1 2 3 4 5
Avatar
Dominique Vaufreydaz
Bonjour,

Positionnement du suivi.

A partir de quand estimez vous que faire une DLL plutot qu'un LIB soit
intéressant. En effet, utiliser des DLL fait des programmes plus
petits (entre autres) mais induit d'enormes contraintes au niveau de
la programmation. Donc d'apres moi, faire une DLL pour une
bibliotheque de petite taille n'est pas forcement une bonne idee...



Je pense (ce n'est que mon avis) qu'il vaut mieux penser
en terme de deploiement. C'est clair qu'ecrire une DLL
qui n'est de toute facon utilisé que par 1 programme ca
sert pas a grand chose, sinon a introduire des problemes
de versionnement de la dite DLL.
Après, avoir 1 DLL juste parcequ'elle fait 1 Mo, ca change
rien. Ton programme aurait ete plus gros d'1 mega.

Maintenant, si ton code est une boite a outils utilisé
possiblement par N programmes sur la machine ca peut
devenir interessant en prenant en compte les points suivants :
- attention aux problemes de version dans le cas où
l'on changerait l'API.
- Si cette API change souvent, on va etre obliger d'avoir
pleins de version de la DLL avec chacun des programmes
ce qui revient a linker statiquement.

Juste mon avis. Doms.
Avatar
Vincent Burel
- Une DLL peut etre chargée dynamiquement par un programme et est
standardisée par le système (alors que les librairies dépendent du langage
utilisé, et ont vocation à etre liées statiquement) .
- Les DLL permettent de scinder un programme en plusieurs parties
indépendantes.

Donc on aura pas besoin de faire de la DLL quand on fait un logiciel
monolithique (qui évidemment n'inclut pas d'architecture plug-in), dont
aucune partie n'est fournit par un tiers, et dont on est certain (dans une
moindre mesure) qu'aucun bout ne devra etre modifié dans le temps
(d'ailleurs pas forcément par l'auteur original). Typiquement on use d'une
DLL quand on pense qu'un bout du soft devra évolué ou pourra etre modifié
selon convenance et contraintes des/du client(s)...

VB

"Korchkidu" wrote in message
news:
Bonjour,

A partir de quand estimez vous que faire une DLL plutot qu'un LIB soit
intéressant. En effet, utiliser des DLL fait des programmes plus
petits (entre autres) mais induit d'enormes contraintes au niveau de la
programmation. Donc d'apres moi, faire une DLL pour une bibliotheque de
petite taille n'est pas forcement une bonne idee...

Merci pour vos commentaires.
K.
Avatar
adebaene
Korchkidu wrote:
Bonjour,

A partir de quand estimez vous que faire une DLL plutot qu'un LIB soit
intéressant. En effet, utiliser des DLL fait des programmes plus
petits (entre autres) mais induit d'enormes contraintes au niveau de la
programmation. Donc d'apres moi, faire une DLL pour une bibliotheque de
petite taille n'est pas forcement une bonne idee...




Même si c'est plus ou moins hors-sujet, j'ajouterais que selon
l'environnement dans lequel tu travailles, une librairie dynamique peut
également être une frontière de sécurité, permettant de définir
les droits et restricitions qu'a le code de la DLL. Les "assemblies"
.NET fonctionnent comme cela par exemple. Cela permet de faire tourner
du code dans lequel on a plus ou moins confiance (téléchargé depuis
Internet, etc...) avec des droits restreints.

Arnaud
Avatar
Korchkidu
Vincent Burel wrote:
- Une DLL peut etre chargée dynamiquement par un programme et est
standardisée par le système (alors que les librairies dépendent du langage
utilisé, et ont vocation à etre liées statiquement) .
- Les DLL permettent de scinder un programme en plusieurs parties
indépendantes.


Les LIB aussi...

Donc on aura pas besoin de faire de la DLL quand on fait un logiciel
monolithique (qui évidemment n'inclut pas d'architecture plug-in), dont
aucune partie n'est fournit par un tiers, et dont on est certain (dans une
moindre mesure) qu'aucun bout ne devra etre modifié dans le temps
(d'ailleurs pas forcément par l'auteur original). Typiquement on use d' une
DLL quand on pense qu'un bout du soft devra évolué ou pourra etre mod ifié
selon convenance et contraintes des/du client(s)...


On peut aussi utiliser une LIB. L'avantage de la reutilisabilite vaut
aussi pour les librairies statiques... Par contre, on devra tout
recompiler a chaque fois, et la, ca peut parfois poser des pb... Quand
par exemple on veut fournir un programme et donner la possibilite au
client de modifier ce qu'il y a "en-dessous"... Mais la effectivement,
c'est plus de plug-in dont on parle...

K.
Avatar
kanze
Korchkidu wrote:

A partir de quand estimez vous que faire une DLL plutot qu'un
LIB soit intéressant. En effet, utiliser des DLL fait des
programmes plus petits (entre autres) mais induit d'enormes
contraintes au niveau de la programmation. Donc d'apres moi,
faire une DLL pour une bibliotheque de petite taille n'est pas
forcement une bonne idee...



L'utilisation du chargement dynamique augmente toujours des
risques de problèmes ; si tu ne peux pas être sûr que l'objet à
charger se trouve sur toutes les machines ciblées, elle pose
aussi un problème de deployement.

Étant donné les problèmes que ça pose, je n'utilise des objets
dynamiques que quand j'ai besoin de ses avantages, c-à-d
sûrtout quand je ne peux pas ou ne veux pas savoir exactement ce
que je charge lors de la création de l'exécutable. Par
exemple :

-- Au moins sous Unix (Solaris), le libc (qui sert sous Unix
comme l'implémentation de l'API du système aussi). Ce qui
permet au même exécutable de tourner sur plusieurs versions
différentes de Solaris : le contenu de l'objet dynamique
est bien différent selon la version de Solaris.

Le même raisonement tient pour la bibliothèque d'interface à
la base de données : l'exécutable doit tourner même dans
les cas où l'utilisateur n'a pas installé la même version de
la base de données que moi (Oracle 7 ou Oracle8, par
exemple).

Note qu'en général, tu ne veux PAS que la bibliothèque C++
soit chargée dynamiquement. Parce que d'une part, elle n'est
pas présente sur beaucoup de machines, et de l'autre, elle a
une tendance à varier de façon incompatible entre des
versions du compilateur, sans parler d'entre des
compilateurs différents. Du coup, si elle est chargée
dynamiquement, il faut que tu t'arranges à la livrer avec
ton exécutable, et il faut que tu prennes des précautions
pour être sûr que c'est bien la version que tu as livrée que
trouve ton programme.

-- Dans les cas où la version de l'objet doit dépendre de
l'environement. Aussi sous Unix, avec le serveur X,
différents utilisateurs utilisent de différentes
gestionnaires de fenêtres, et un utilisateur de KDE ne veut
pas forcément des widgets Motif, et vice versa (encore que
KDE supporte un look-n-feel Motif aussi). On lit donc
l'information sur quel objet de gestion graphique a charger
d'une variable d'environement, et on charge l'un ou l'autre,
selon.

-- Dans les cas de fonctionnements évolutifs, pour ajouter des
fonctionnements par la suite, où si les fonctions
disponibles doivent varier selon l'environement. Mes modules
UTF-8, par exemple, utilise des objets dynamiques pour
effectuer les transcodages en entrée et en sortie -- je ne
sais pas aujourd'hui quels encodages j'aurai à supporter, et
pour en supporter un nouveau, il suffit d'installer un objet
dynamique à l'endroit prévu.

En dehors du premier cas (qui est assez limité), c'est prèsque
toujours un chargement explicit (dlopen ou LoadLibrary, selon le
système) qu'il faut. C'est très, très rare d'utiliser un
chargement dynamique implicit, sauf que pour la bibliothèque
système (sous Unix) ou la base de données.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Avatar
Rémy
"kanze" a écrit dans le message de news:


En dehors du premier cas (qui est assez limité), c'est prèsque
toujours un chargement explicit (dlopen ou LoadLibrary, selon le
système) qu'il faut. C'est très, très rare d'utiliser un
chargement dynamique implicit, sauf que pour la bibliothèque
système (sous Unix) ou la base de données.



Nous utilisons des DLL (en fait des .so) pour les modules communs
d'applications composées de plusieurs (dizaines) de processus.
Ca n'apporte rien fonctionnellement par rapport à l'édition de liens
statique, mais ça économise considérablement la mémoire car le code n'est
présent qu'une fois en mémoire.
Par ailleurs, ça permet de livrer les corrections des modules communs sans
que le programme les utilisant n'ait à être relinké.
Avatar
kanze
Rémy wrote:
"kanze" a écrit dans le message de news:




> En dehors du premier cas (qui est assez limité), c'est prèsque
> toujours un chargement explicit (dlopen ou LoadLibrary, selon le
> système) qu'il faut. C'est très, très rare d'utiliser un
> chargement dynamique implicit, sauf que pour la bibliothèque
> système (sous Unix) ou la base de données.



Nous utilisons des DLL (en fait des .so) pour les modules
communs d'applications composées de plusieurs (dizaines) de
processus. Ca n'apporte rien fonctionnellement par rapport à
l'édition de liens statique, mais ça économise
considérablement la mémoire car le code n'est présent qu'une
fois en mémoire.



En es-tu certain ? Ce n'est pas ce que j'ai compris jusqu'ici,
et ça ne correspond pas au nom. Au moins sous Windows : je sais
que la taille était bien la motivation principale des « shared
objects » sous Sun OS, dans le temps, mais je croyais qu'il
s'agissait principalement de la taille sur disque (à une époque
où la taille des disques se mesurait en Mo, et non Go, et que la
taille de la bibliothèque graphique était bien plusieurs Mo).
C'est possible que l'image en mémoire soit partagé ; c'est même
l'idée derrière le PIC (« position independant code », mais ça
augmente aussi la vitesse de chargement de façon notable, même
si l'image n'est pas partagé). Mais ça suppose aussi que l'objet
partagé ne réfère jamais à rien dans le main, et que s'il réfère
à quelque chose dans un autre objet partagé (libc, par exemple),
que cet autre objet soit lié à la même adresse dans tous les
exécutables (rélative à l'adresse de mon objet partagé, au
moins).

Par ailleurs, ça permet de livrer les corrections des modules
communs sans que le programme les utilisant n'ait à être
relinké.



C'est justement le gros problème. L'utilisateur finit très vite
avec un melange de versions incompatibles.

Ici, ils avaient fait à peu près pareil, avec l'idée
qu'effectivement, la plupart des bibliothèques servaient à
plusieurs exécutables. Seulement, juste au moment où j'y suis
arrivé, on a eu des crashs en production parce que
$LD_LIBRARY_PATH ne désignait pas le chemin vers la bonne
version de la bibliothèque -- un peu de récherche a montré
qu'en fait, les versions des exécutables (livrées par des
équipes différentes) étaient telles que chaque exécutable avait
besoin d'une version différente des bibliothèques. Les
bibliothèques étaient donc présentes autant de fois qu'il y
avait d'exécutables, dans de versions différentes. Pas de gain
de place, donc, et une risque réele de chopper la mauvaise
version.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Avatar
Dominique Vaufreydaz
Bonjour,

Nous utilisons des DLL (en fait des .so) pour les modules
communs d'applications composées de plusieurs (dizaines) de
processus. Ca n'apporte rien fonctionnellement par rapport à
l'édition de liens statique, mais ça économise



En es-tu certain ? Ce n'est pas ce que j'ai compris jusqu'ici,
et ça ne correspond pas au nom. Au moins sous Windows : je sais



A priori, oui, et depuis longtemps les DLLs sont partagées en
memoire et mappées dans les espaces memoires des processus
l'utilisant.

Doms.
Avatar
Rémy
"kanze" a écrit dans le message de news:

Rémy wrote:

Nous utilisons des DLL (en fait des .so) pour les modules
communs d'applications composées de plusieurs (dizaines) de
processus. Ca n'apporte rien fonctionnellement par rapport à
l'édition de liens statique, mais ça économise
considérablement la mémoire car le code n'est présent qu'une
fois en mémoire.





En es-tu certain ? Ce n'est pas ce que j'ai compris jusqu'ici,
et ça ne correspond pas au nom. Au moins sous Windows : je sais
que la taille était bien la motivation principale des « shared
objects » sous Sun OS, dans le temps, mais je croyais qu'il
s'agissait principalement de la taille sur disque (à une époque
où la taille des disques se mesurait en Mo, et non Go, et que la
taille de la bibliothèque graphique était bien plusieurs Mo).



Oui (en tout cas sur les OS sur lesquels je travaille habituellement : Sun
OS, HP-UX, Tru 64 et Linux.

C'est possible que l'image en mémoire soit partagé ; c'est même
l'idée derrière le PIC (« position independant code », mais ça
augmente aussi la vitesse de chargement de façon notable, même
si l'image n'est pas partagé).



Oui, aussi.

Mais ça suppose aussi que l'objet
partagé ne réfère jamais à rien dans le main,



Effectivement, il vaut mieux que le .so ne réfère rien dans le main...
Mais pour des composants communs, il vaut mieux ne pas dépendre de
l'utilisateur.
Seulement d'autres composants communs et encore, en évitant les dépendances
circulaires...

et que s'il réfère
à quelque chose dans un autre objet partagé (libc, par exemple),
que cet autre objet soit lié à la même adresse dans tous les
exécutables (rélative à l'adresse de mon objet partagé, au
moins).



Ma foi, je pense que c'est le boulot de l'édition de lien dynamique
d'assurer que ça marche.
Je ne sais pas s'il est nécessaire que les objets soient à la même adresse
dans tous les exécutables ?

Par ailleurs, ça permet de livrer les corrections des modules
communs sans que le programme les utilisant n'ait à être
relinké.





C'est justement le gros problème. L'utilisateur finit très vite
avec un melange de versions incompatibles.



Il y a un travail sérieux pour s'assurer de la compatibilité ascendante.
Il n'y a pas de "mélange" de version car (dans notre cas) une nouvelle
version remplace la précédente (les composants communs sont installés une
seule fois sur la machine et pas avec chaque exécutable).


Ici, ils avaient fait à peu près pareil, avec l'idée
qu'effectivement, la plupart des bibliothèques servaient à
plusieurs exécutables. Seulement, juste au moment où j'y suis
arrivé, on a eu des crashs en production parce que
$LD_LIBRARY_PATH ne désignait pas le chemin vers la bonne
version de la bibliothèque



Problème effectivement si on installe plusieurs versions sur la même machine

-- un peu de récherche a montré
qu'en fait, les versions des exécutables (livrées par des
équipes différentes) étaient telles que chaque exécutable avait
besoin d'une version différente des bibliothèques.



Si chacun fait évoluer les composants communs de façon incompatible... Eh
bien, ils ne sont plus communs...
Je pense que ce n'est faisable qu'avec une organisation adaptée.
Dans notre cas, il y a une équipe chargée de toutes les livraisons qui
réceptionne les sources de tous les produits (communs ou pas), recompile
tout sur une machine dédiée et génère les produits à installer.

Les bibliothèques étaient donc présentes autant de fois qu'il y
avait d'exécutables, dans de versions différentes. Pas de gain
de place, donc, et une risque réele de chopper la mauvaise
version.



C'est comme beaucoup d'outils, si on s'en sert mal (ou sans les contrôler),
on peut faire de gros dégâts ;-)
Avatar
Alain Gaillard
kanze a écrit :

En es-tu certain ?



Il peut l'être sous Windows.


Ce n'est pas ce que j'ai compris jusqu'ici,
et ça ne correspond pas au nom. Au moins sous Windows



Mon bon James, tu manques un peu d'expérience dans le domaine ;)
(pardonne moi mais je n'ai pas pu m'en empêcher:) )
Sous Windows les dll ne sont chargées qu'une fois en mémoire, ce qui est
heureux car sinon tout le système, qui est constitué uniquement de dll
serait chargé par chaque application. kernel32.dll, user32.dll. Tu
imagines ?

Le mécanisme de gestion de mémoire virtuelle est assez particulier. En
quelques mots disons que toute application se voit attribuer les 4 Go
adressables, mais toute cette zone est une zone de mémoire virtuelle,
pas physique évidemment. Les 2 go de mémoire basse sont à son usage.
Dans les 2 Go de mémoire haute sont installée les tables de saut vers
les dll utilisées par l'application, comme par exemple kernel32.dll,
user32.dll, madll.dll. Je parle bien ici de mémoire virtuelle.

Quand une appli appelle une fonction de dll, elle saute quelque part
dans ces deux Go de mémoire haute puis de là saute dans la mémoire
*physique* où est effectivement chargée la dll. Et cette dll ne réside
qu'une fois en mémoire physique.

--
Alain
1 2 3 4 5