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

Avatar
Vincent Burel
"kanze" wrote in message
news:
Vincent Burel wrote:
"James Kanze" wrote in message
news:
Alain Gaillard wrote:
> kanze a écrit :



[...]
Le problème n'est pas vraiment pour les fonctions. Je reconnais
bien qu'un niveau d'indirection supplémentaire pourrait faire
l'affaire (et encore, il y a des cas où ça ne doit pas être
évident). Le problème, c'est les données statiques.



Non, parce qu'une DLL (ou un exe) ne gère que des adresse 32
bit (qui sont que des offset en fait), le système lui gère
aussi les segments, et peut faire en sorte qu'un code
s'éxécute avec le bon segment de données (et bien sur le bon
segement de pile etc...).



Mais alors, il faudrait des pointeurs FAR, à 48 bits, ou ?

ben c'est à dire que chaque "task" s'exécute dans un environnement mémoire
propre, et en fonction d'une table de mappage mem-phy <-> mem logique
spécique. Quand le programme fait appel à une adresse 32 bit, c'est toujours
dans un contexte mémoire donné...

il faut lire le "IA-32 Intel ® Architecture Software Developer's Manual Vol
ume 3 : System Programming Guide" (document 25366814.pdf téléchargeable chez
intel) qui explique les différents models mémoires... on peut supposer que
windows utilise le Multi Segment Model où chaque "task" a son jeu de
segement (CS, SS, DS, ES, FS, GS) et de table de descripteur (LDT). Et qu'en
plus, windows utilise le paging, qui permet de découper la mémoire en
tranche de 4kB (par exemple), et de faire autant de mapping (logique to
physique) différent... Notons que c'est le processor qui s'occupe de la
translation logique to physique, selon la LDT (ou GDT pour le system) et
peut génère une exception-fault si la page demandée n'est pas en mémoire
physique (et c'est la que le systeme peut prendre la main, pour monter de la
swap par exemple)...

hou que c'est compliquer ce bins ! :-) Et pour avoir fait une bribe d'OS y'a
quelque temps, (et juste en model flat) je peux vous dire que la mise en
oeuvre est encore plus compliqué :-)

VB
Avatar
Alain Gaillard
James Kanze a écrit :


Je sais que le 80386 introduisait un mechanisme pour supporter
ce genre de chose -- un appel FAR pouvait passer par un espèce
de portail qui faisait qu'on ne pourrait arriver qu'à des
adresses bien définies, mais qu'on ce faisant, on passait en
mode super-user.



Encore ce terme de FAR.... :-S
Mais globalement c'ets comme ce que tu décris.


règistre, et puis d'utiliser un « trap » -- sur une 80x86, une
instruction INT -- qui passe par une table d'interruptions (que
le code utilisateur ne peut pas modifier, au moins en mode
protégée du processeur).



Certes mais sous Windows ce n'est pa scomme ça.

machine. Même aujourd'hui, je vois mal un système qui mappe l'OS
et l'application utilisateur dans le même espace virtuel.



Tu le vois mal ? Alors change de lunettes, puisque c'est comme ça :)


J'avais oublié le :-). L'idée qu'un processus utilisateur ne
peut se servir de 2 Go, à la place de 4,



A mais je n'ai jamais dis ça. Faut lire....
J'ai dit:

4go adressables pour un processus.
Le code est dans les 2 go inférieurs. Pour être plus complet, tout en
bas de cette zone, il y a un cache (PATH, clé de registre, etc...) qui
est réservé par le système, dans le sens où l'appli ne peut pas écrire
dedans
Les tables de saut sont dans les é Go supérieurs. Ainsi que les données,
ça je ne l'ai aps précisé.

En gros, une appli dispose d'environ 3 go vraiment pour elle.



sur un processeur
moderne 32 bits avec mémoire virtuelle, me faisait en fait
penser au commentaire « 564 [ou quelque chose comme ça] mémoire
serait assez grande pour n'importe qui », attribué à Bill Gates
(faussement, je crois).



Je ne sais pas. Mais je sais qu'il a dit "Si vous ne pouvez pas le faire
bien, faites le beau" LOL



Alors, comme fait-il ? Le problème reste que dans un code ultra
simple :

int
f()
{
static int i = 0 ;
return i ++ ;
}

le compilateur génère une adresse absolue pour i.



Certes, mais en quoi c'est un problème ?


J'avoue que je suis curieux en ce qui concerne la solution.



Et bien je t'encourages à lire les docs de Kro$oft.
D'ailleurs quelqu'un a donnée des liens, tu peux aller voir et de fil en
aiguille, tu trouveras toutes les infos que tu souhaites je pense.


--
Alain
Avatar
Vincent Burel
"Vincent Burel" wrote in message
news:45051cd1$0$5110$

"kanze" wrote in message
news:
Vincent Burel wrote:
> "James Kanze" wrote in message
> news:

> [...]
ben c'est à dire que chaque "task" s'exécute dans un environnement mémoire
propre, et en fonction d'une table de mappage mem-phy <-> mem logique
spécique. Quand le programme fait appel à une adresse 32 bit, c'est


toujours
dans un contexte mémoire donné...
[...]



j'ai oublier de conclure, mais cela veux dire que le systme (windows en tout
cas) peut mapper la mémoire logique comme bon lui semble en mémoire physique
(par page évidemment) et que même si le programme (exe ou DLL) est compilé
dans un espace logique linéaire de 4 Go (adress 32 bit), avant éxécution, le
systeme peut reloger tout ou partie du code et des données, n'importe où
dans la mémoire physique, dans le désordre ou pas, fragmenté ou pas... Alors
que lui continuera de travailler avec des adresse logique, et voir la
mémoire comme un espace linéaire et continue de 4Go...

VB
Avatar
Alain Gaillard
Vincent Burel a écrit :

j'ai oublier de conclure, mais cela veux dire que le systme (windows en tout
cas) peut mapper la mémoire logique comme bon lui semble en mémoire physique
(par page évidemment) et que même si le programme (exe ou DLL) est compilé
dans un espace logique linéaire de 4 Go (adress 32 bit), avant éxécution, le
systeme peut reloger tout ou partie du code et des données, n'importe où
dans la mémoire physique, dans le désordre ou pas, fragmenté ou pas... Alors
que lui continuera de travailler avec des adresse logique, et voir la
mémoire comme un espace linéaire et continue de 4Go...



Parfaitement exact et bien dit :)

--
Alain
Avatar
Arnold McDonald \(AMcD\)
Alain Gaillard wrote:
Arnold McDonald (AMcD) a écrit :



En effet tu lis en diagonale, car d'abord je ne vois pas en quoi cette
discussion est une engueulo.



Ne serait-ce que ton ton "je suis le best je sais tout", ça donen une vague
idée de franche camaraderie.

Déjà, ce n'est pas le processeur qui possède la mémoire virtuelle
("un processeur moderne 32 bits avec mémoire virtuelle"),



On a pas dit ça ce me semble.



Je cite l'intervenant précédent :

"sur un processeur moderne 32 bits avec mémoire virtuelle"

On a pas dit ça non plus, dès le début de la discussion j'ai dit:
'les 4 g0 adressables pour le processus." et les tables de saut des
dll sont toujours dans les 2 go supérieurs



Alors tu ne comprends pas bien ou ne sait pas lire. Je cite encore
l'intervenant précédent :

"L'idée qu'un processus utilisateur ne peut se servir de 2 Go, à la place de
4,"

Je répète, il y a bien longtemps que l'on peut adresser plus de 4 Go et que
plus de 2 Go sont utilisables par un processus.

PS : garde ton ton docte pour les autres, t'es mal tombé avec moi.

--
Arnold McDonald (AMcD)

http://arnold.mcdonald.free.fr/
Avatar
Manuel Zaccaria
Alain Gaillard a écrit:

En effet tu te trompes, la table de sauts est constituée à l'appel de
LoadLibrary. GetProcAddress ne fait que retourner une e addresse dans la
table.



Autant pour moi! Merci pour le correctif. (Quel gaspi quand même...)

Manuel
Avatar
kanze
Alain Gaillard wrote:
kanze a écrit :



> Mais alors, il faudrait des pointeurs FAR, à 48 bits, ou ?



??



Si l'OS s'amuse à jouer avec les règistres de segmentation.

En fait, il s'agit toujours de la fonction :

int
f()
{
static int i = 0 ;
return i ++ ;
}

Dans le code généré par VC++, les instructions d'accès à i
utilise un offset constant (à l'encontre de ce qui se passe avec
g++ -fpei sous Linux, par exemple). Cet offset, c'est par
rapport à DS. Alors, je compile cette fonction, et je le lie
dans une DLL. Je charge la DLL dans deux processus différents,
dont les données, etc., se trouvent à des adresses différentes.
Comment fait Windows pour que ce bout de code fonctionne ? S'il
partage l'image du code entre plusieurs processus, il ne peut
pas « corriger » l'offset dans le code. Si on ne se sert pas
des pointeurs 48 bits (avec chaque fois un segment, et un
segment par DLL), il ne peut pas s'assurer que l'offset soit
identique dans chaque processus. Alors, que fait-il ? (Il doit
bien y avoir quelque chose que je ne vois pas, parce
qu'indubitablement, ça marche.)

--
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
kanze
Vincent Burel wrote:
"kanze" wrote in message
news:
Vincent Burel wrote:
> "James Kanze" wrote in message
> news:
> Alain Gaillard wrote:
> > kanze a écrit :



> [...]
> Le problème n'est pas vraiment pour les fonctions. Je reconnais
> bien qu'un niveau d'indirection supplémentaire pourrait faire
> l'affaire (et encore, il y a des cas où ça ne doit pas être
> évident). Le problème, c'est les données statiques.



> Non, parce qu'une DLL (ou un exe) ne gère que des adresse 32
> bit (qui sont que des offset en fait), le système lui gère
> aussi les segments, et peut faire en sorte qu'un code
> s'éxécute avec le bon segment de données (et bien sur le bon
> segement de pile etc...).



Mais alors, il faudrait des pointeurs FAR, à 48 bits, ou ?



ben c'est à dire que chaque "task" s'exécute dans un
environnement mémoire propre, et en fonction d'une table de
mappage mem-phy <-> mem logique spécique. Quand le programme
fait appel à une adresse 32 bit, c'est toujours dans un
contexte mémoire donné...



Certes, mais qu'est-ce que ça change ? Je parle bien ici de
l'adresse dans l'espace d'adressage d'un processus. Le
compilateur génère une adresse constante (par rapport à DS, en
tout cas).

il faut lire le "IA-32 Intel ® Architecture Software
Developer's Manual Vol ume 3 : System Programming Guide"
(document 25366814.pdf téléchargeable chez intel) qui explique
les différents models mémoires...



Je les connais assez bien, ayant enseigné l'assembleur 8086 pour
Intel dans le temps.

on peut supposer que windows utilise le Multi Segment Model où
chaque "task" a son jeu de segement (CS, SS, DS, ES, FS, GS)
et de table de descripteur (LDT). Et qu'en plus, windows
utilise le paging, qui permet de découper la mémoire en
tranche de 4kB (par exemple), et de faire autant de mapping
(logique to physique) différent... Notons que c'est le
processor qui s'occupe de la translation logique to physique,
selon la LDT (ou GDT pour le system) et peut génère une
exception-fault si la page demandée n'est pas en mémoire
physique (et c'est la que le systeme peut prendre la main,
pour monter de la swap par exemple)...



Tout ça c'est bien beau, même si j'imagine mal quelqu'un qui ne
le connais pas. (J'ai aussi travaillé sur des noyaux temps-réels
pour 80386. Qui avait déjà la mémoire virtuelle -- à deux
niveaux --, en plus des segments.) Mais ça ne résoud pas notre
problème, qui ne concerne que l'adresse logique à l'interier du
processus. D'autant que je puisse établir, d'après le code
généré, l'offset d'une variable statique dans la fonction est
constante. C-à-d que l'accès utilise un adressage absolu (par
rapport à DS, s'entende). Et je constate également qu'à
l'intérieur d'un processus, on ne touche normalement pas à
DS -- si la fonction renvoie l'adresse, par exemple, il renvoie
bien l'offset, sans renseigner sur le segment (qu'a priori ne
change pas). J'ai donc, dans l'image partagé par plusieurs
processes une constante (dans l'image) qui représente cette
adresse. Seulement, c'est impossible que l'adresse logique soit
la même dans tous les processus. Alors, il y a quelque chose que
je ne comprends pas.

--
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
kanze
Alain Gaillard wrote:
Vincent Burel a écrit :



> j'ai oublier de conclure, mais cela veux dire que le systme
> (windows en tout cas) peut mapper la mémoire logique comme
> bon lui semble en mémoire physique (par page évidemment) et
> que même si le programme (exe ou DLL) est compilé dans un
> espace logique linéaire de 4 Go (adress 32 bit), avant
> éxécution, le systeme peut reloger tout ou partie du code et
> des données, n'importe où dans la mémoire physique, dans le
> désordre ou pas, fragmenté ou pas... Alors que lui
> continuera de travailler avec des adresse logique, et voir
> la mémoire comme un espace linéaire et continue de 4Go...



Parfaitement exact et bien dit :)



Et complètement sans intérêt pour le problème en question. Et
sans doute bien connu de tout le monde aujourd'hui, parce que
pareil sur tous les systèmes d'exploitation, depuis belle
lurette. (Ce sont des versions Berkley sur VAX qui l'ont
introduit sur Unix. Environ 1977. Intel en a introduit le
supporter hardware sur leurs processeurs avec le 432, et dans la
famille 80x86, au moins depuis le 80386. Même si Microsoft a
préféré attendre le milieu des années 1990 pour l'exploiter.)

Le problème est simple. Le code généré de ma fonction utilise
l'adressage absolu (toujours par rapport au segment,
évidemment). C-à-d qu'une fois linké, l'adresse logique dans le
processus est figée ; pour la changer, il faudrait changer
l'image du code. Seulement, selon la reste du programme, les
adresses logiques disponibles ne sont pas les mêmes. Et si
l'image de code est identique chez tous les utilisateurs de la
DLL, le système ne peut pas faire des corrections là non plus.

--
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
Alain Gaillard
Arnold McDonald (AMcD) a écrit :


En effet tu lis en diagonale, car d'abord je ne vois pas en quoi cette
discussion est une engueulo.




Ne serait-ce que ton ton "je suis le best je sais tout", ça donen une vague
idée de franche camaraderie.



Tu te trompes. En tout.
James et moi discutions, nous ne nous engueulions pas. Donc tu as mal
commencé ton intervention. Il me semble qur si tu veux intervenir dans
une discussion, la moindre des choses et de lire ce qui a été écrit

C'est dommage que tu prennes ça comme ça. Tu vois des engueulo là il n'y
en a pas et tu es presque déjà en train d'ne provoquer une.



PS : garde ton ton doct



Encore une fois tu te trompes, mais bon peu importe.


--
Alain