Je vois déjà un problème ici. Ce typedef, en réalité,
peut représenter PLUSIEURS types.
Oui et non. En tant que type, c'est bien un seul type. En
revanche, il est clair qu'il faut que tous les objets linkés
dans le programme (qu'ils soient linké dynamiquement ou
statiquement) soit compilés avec le même compilateur et les
mêmes options. Qu'on ait une version débug dans un des fichiers
objets et une version optimisée dans un autre, et il y a des
chances que ça ne marche pas.
Aussi, il faut faire gaffe en ce qui concerne les parties qui
dépendent des objets statiques -- dans le cas d'un map, par
exemple, l'allocateur (qui utilise une structure statique pour
gérer la memoire). Il ne faut pas qu'ils utilisent une instance
une fois, et une autre instance une autre fois. Ce qui
correspond à des options par défaut sous Unix, mais qui, d'après
ce que j'ai entendu dire, n'est pas le défaut sous Unix.
Un MyMap pour chaque dll (debug/release) plus un MyMap pour
chaque exe (debug/release) et que sais-je encore. Les options
de compilations, etc, etc. Il y a de fortes chances qu'ils
soient très différents.
A priori, dans un cas comme le sien, je dirais non. C'est un
petit exemple ; logiquement, il aurait tout compilé avec les
mêmes options. (Note bien aussi que le problème des options
n'est pas propre au chargement dynamique. J'ai déjà eu des
problèmes parce que certains objets avaient été compilé avec
debug, d'autres non, avec g++ et linké statiquement.)
Pas simplement en tous cas.. là, je dois partir maintenant.
Mais juste un conseil: utiliser des POD, pas des classes. (et
surtout qu'en plus ce sont des templates ce qui n'aide pas)
Je ne sais pas. Je me sers regulièrement des classes assez
complexes dans les objets dynamiques. Typiquement, d'ailleurs,
ce que j'exporte est une classe d'interface : que des fonctions
virtuelles pûres. L'objet dynamique contient une fonction usine
pour les créer, et le code utilisateur ne voit jamais de membres
donnés ni de fonction directement. Dans la pratique, ça permet
de compiler avec des options différentes aussi. (Note qu'avec
cette solution, dans son cas, le map n'apparaîtra que dans la
DLL.)
Je vois déjà un problème ici. Ce typedef, en réalité,
peut représenter PLUSIEURS types.
Oui et non. En tant que type, c'est bien un seul type. En
revanche, il est clair qu'il faut que tous les objets linkés
dans le programme (qu'ils soient linké dynamiquement ou
statiquement) soit compilés avec le même compilateur et les
mêmes options. Qu'on ait une version débug dans un des fichiers
objets et une version optimisée dans un autre, et il y a des
chances que ça ne marche pas.
Aussi, il faut faire gaffe en ce qui concerne les parties qui
dépendent des objets statiques -- dans le cas d'un map, par
exemple, l'allocateur (qui utilise une structure statique pour
gérer la memoire). Il ne faut pas qu'ils utilisent une instance
une fois, et une autre instance une autre fois. Ce qui
correspond à des options par défaut sous Unix, mais qui, d'après
ce que j'ai entendu dire, n'est pas le défaut sous Unix.
Un MyMap pour chaque dll (debug/release) plus un MyMap pour
chaque exe (debug/release) et que sais-je encore. Les options
de compilations, etc, etc. Il y a de fortes chances qu'ils
soient très différents.
A priori, dans un cas comme le sien, je dirais non. C'est un
petit exemple ; logiquement, il aurait tout compilé avec les
mêmes options. (Note bien aussi que le problème des options
n'est pas propre au chargement dynamique. J'ai déjà eu des
problèmes parce que certains objets avaient été compilé avec
debug, d'autres non, avec g++ et linké statiquement.)
Pas simplement en tous cas.. là, je dois partir maintenant.
Mais juste un conseil: utiliser des POD, pas des classes. (et
surtout qu'en plus ce sont des templates ce qui n'aide pas)
Je ne sais pas. Je me sers regulièrement des classes assez
complexes dans les objets dynamiques. Typiquement, d'ailleurs,
ce que j'exporte est une classe d'interface : que des fonctions
virtuelles pûres. L'objet dynamique contient une fonction usine
pour les créer, et le code utilisateur ne voit jamais de membres
donnés ni de fonction directement. Dans la pratique, ça permet
de compiler avec des options différentes aussi. (Note qu'avec
cette solution, dans son cas, le map n'apparaîtra que dans la
DLL.)
Je vois déjà un problème ici. Ce typedef, en réalité,
peut représenter PLUSIEURS types.
Oui et non. En tant que type, c'est bien un seul type. En
revanche, il est clair qu'il faut que tous les objets linkés
dans le programme (qu'ils soient linké dynamiquement ou
statiquement) soit compilés avec le même compilateur et les
mêmes options. Qu'on ait une version débug dans un des fichiers
objets et une version optimisée dans un autre, et il y a des
chances que ça ne marche pas.
Aussi, il faut faire gaffe en ce qui concerne les parties qui
dépendent des objets statiques -- dans le cas d'un map, par
exemple, l'allocateur (qui utilise une structure statique pour
gérer la memoire). Il ne faut pas qu'ils utilisent une instance
une fois, et une autre instance une autre fois. Ce qui
correspond à des options par défaut sous Unix, mais qui, d'après
ce que j'ai entendu dire, n'est pas le défaut sous Unix.
Un MyMap pour chaque dll (debug/release) plus un MyMap pour
chaque exe (debug/release) et que sais-je encore. Les options
de compilations, etc, etc. Il y a de fortes chances qu'ils
soient très différents.
A priori, dans un cas comme le sien, je dirais non. C'est un
petit exemple ; logiquement, il aurait tout compilé avec les
mêmes options. (Note bien aussi que le problème des options
n'est pas propre au chargement dynamique. J'ai déjà eu des
problèmes parce que certains objets avaient été compilé avec
debug, d'autres non, avec g++ et linké statiquement.)
Pas simplement en tous cas.. là, je dois partir maintenant.
Mais juste un conseil: utiliser des POD, pas des classes. (et
surtout qu'en plus ce sont des templates ce qui n'aide pas)
Je ne sais pas. Je me sers regulièrement des classes assez
complexes dans les objets dynamiques. Typiquement, d'ailleurs,
ce que j'exporte est une classe d'interface : que des fonctions
virtuelles pûres. L'objet dynamique contient une fonction usine
pour les créer, et le code utilisateur ne voit jamais de membres
donnés ni de fonction directement. Dans la pratique, ça permet
de compiler avec des options différentes aussi. (Note qu'avec
cette solution, dans son cas, le map n'apparaîtra que dans la
DLL.)
kanze a écrit:
Et dans six mois ? Il faut recompiler les 50 modules car on a
une nouvelle version du compilateur ?
kanze a écrit:
Et dans six mois ? Il faut recompiler les 50 modules car on a
une nouvelle version du compilateur ?
kanze a écrit:
Et dans six mois ? Il faut recompiler les 50 modules car on a
une nouvelle version du compilateur ?
[...]
Je suis absolument d'accord et je le fais souvent car une classe
d'interface n'exprime qu'un contrat et ne pollue pas le client.
Les usines sont aussi un composant essentiel; les objets que
je crée avec sont détruits à coup de 'delete this' et ils ont
tous un destructeur inaccessible au code client (y compris les
interfaces, il n'y a pas de destructeur virtuel dans ce cas).
[...]
Je suis absolument d'accord et je le fais souvent car une classe
d'interface n'exprime qu'un contrat et ne pollue pas le client.
Les usines sont aussi un composant essentiel; les objets que
je crée avec sont détruits à coup de 'delete this' et ils ont
tous un destructeur inaccessible au code client (y compris les
interfaces, il n'y a pas de destructeur virtuel dans ce cas).
[...]
Je suis absolument d'accord et je le fais souvent car une classe
d'interface n'exprime qu'un contrat et ne pollue pas le client.
Les usines sont aussi un composant essentiel; les objets que
je crée avec sont détruits à coup de 'delete this' et ils ont
tous un destructeur inaccessible au code client (y compris les
interfaces, il n'y a pas de destructeur virtuel dans ce cas).
En général, le chargement dynamique est une source de problèmes
et d'instabilités. On l'évite quand on n'en as pas explicitement
besoin -- dans un programme applicatif qui ne supporte pas de
plugins, il n'y a que des bibliothèques du système et des
produits tièrce (base de données, etc.) qui doivent être chargé
dynamique. Mettre diverses parties de l'application dans de
différentes DLL's n'a que de désavantages.
Le problème viens dès que l'on a des plug-ins.
Je me retrouve très souvent dans le cas où j'ai des plug-ins
qui utilisent une infrastructure commune. Et bien, je me
retrouve souvent obligé de mettre cette architecture dans une
DLL aussi, car sinon, la mémoire globale (et donc les
singletons) gérée pas cette bibliothèque se trouve dupliquée
par DLL de plug-in, ce qui n'est pas sans poser de problèmes.
Autre cas d'utilisation de DLL : .NET... Il n'y a pas de
linker avec ce framework, et tout passe donc par des
bibliothèques dynamiques :(
En général, le chargement dynamique est une source de problèmes
et d'instabilités. On l'évite quand on n'en as pas explicitement
besoin -- dans un programme applicatif qui ne supporte pas de
plugins, il n'y a que des bibliothèques du système et des
produits tièrce (base de données, etc.) qui doivent être chargé
dynamique. Mettre diverses parties de l'application dans de
différentes DLL's n'a que de désavantages.
Le problème viens dès que l'on a des plug-ins.
Je me retrouve très souvent dans le cas où j'ai des plug-ins
qui utilisent une infrastructure commune. Et bien, je me
retrouve souvent obligé de mettre cette architecture dans une
DLL aussi, car sinon, la mémoire globale (et donc les
singletons) gérée pas cette bibliothèque se trouve dupliquée
par DLL de plug-in, ce qui n'est pas sans poser de problèmes.
Autre cas d'utilisation de DLL : .NET... Il n'y a pas de
linker avec ce framework, et tout passe donc par des
bibliothèques dynamiques :(
En général, le chargement dynamique est une source de problèmes
et d'instabilités. On l'évite quand on n'en as pas explicitement
besoin -- dans un programme applicatif qui ne supporte pas de
plugins, il n'y a que des bibliothèques du système et des
produits tièrce (base de données, etc.) qui doivent être chargé
dynamique. Mettre diverses parties de l'application dans de
différentes DLL's n'a que de désavantages.
Le problème viens dès que l'on a des plug-ins.
Je me retrouve très souvent dans le cas où j'ai des plug-ins
qui utilisent une infrastructure commune. Et bien, je me
retrouve souvent obligé de mettre cette architecture dans une
DLL aussi, car sinon, la mémoire globale (et donc les
singletons) gérée pas cette bibliothèque se trouve dupliquée
par DLL de plug-in, ce qui n'est pas sans poser de problèmes.
Autre cas d'utilisation de DLL : .NET... Il n'y a pas de
linker avec ce framework, et tout passe donc par des
bibliothèques dynamiques :(
gbaudin a écrit:Je n'aurais pas penser que le type template pouvait
provoquer cette erreur
Ce n'est pas ce que j'ai dit. Avec les templates, le code
client a une dépendance facheuse avec l'implémentation,
private ou pas. Ca aide ça ?J'ai quand même du mal a comprendre pourquoi
map<string,string> n'est pas considéré de même type dans
l'exe et dans la dll ...
Oh mais pour le compilateur il s'agît du même type (comme
James Kanze l'a justement souligné) mais quand on ment au
compilateur... il se venge.
gbaudin a écrit:
Je n'aurais pas penser que le type template pouvait
provoquer cette erreur
Ce n'est pas ce que j'ai dit. Avec les templates, le code
client a une dépendance facheuse avec l'implémentation,
private ou pas. Ca aide ça ?
J'ai quand même du mal a comprendre pourquoi
map<string,string> n'est pas considéré de même type dans
l'exe et dans la dll ...
Oh mais pour le compilateur il s'agît du même type (comme
James Kanze l'a justement souligné) mais quand on ment au
compilateur... il se venge.
gbaudin a écrit:Je n'aurais pas penser que le type template pouvait
provoquer cette erreur
Ce n'est pas ce que j'ai dit. Avec les templates, le code
client a une dépendance facheuse avec l'implémentation,
private ou pas. Ca aide ça ?J'ai quand même du mal a comprendre pourquoi
map<string,string> n'est pas considéré de même type dans
l'exe et dans la dll ...
Oh mais pour le compilateur il s'agît du même type (comme
James Kanze l'a justement souligné) mais quand on ment au
compilateur... il se venge.
kanze a écrit:Je vois déjà un problème ici. Ce typedef, en réalité,
peut représenter PLUSIEURS types.
Oui et non. En tant que type, c'est bien un seul type. En
revanche, il est clair qu'il faut que tous les objets linkés
dans le programme (qu'ils soient linké dynamiquement ou
statiquement) soit compilés avec le même compilateur et les
mêmes options. Qu'on ait une version débug dans un des
fichiers objets et une version optimisée dans un autre, et
il y a des chances que ça ne marche pas.
J'en suis conscient, je me suis assez cassé les dents dessus.
Aussi, il faut faire gaffe en ce qui concerne les parties
qui dépendent des objets statiques -- dans le cas d'un map,
par exemple, l'allocateur (qui utilise une structure
statique pour gérer la memoire). Il ne faut pas qu'ils
utilisent une instance une fois, et une autre instance une
autre fois. Ce qui correspond à des options par défaut sous
Unix, mais qui, d'après ce que j'ai entendu dire, n'est pas
le défaut sous Unix.
J'essaie de ne pas avoir d'objets statiques dans mes modules.
Pour l'instant j'en ai jamais eu besoin. J'allume un cierge.
[...]
Et dans six mois ? Il faut recompiler les 50 modules car on a
une nouvelle version du compilateur ?
Pas simplement en tous cas.. là, je dois partir maintenant.
Mais juste un conseil: utiliser des POD, pas des classes.
(et surtout qu'en plus ce sont des templates ce qui n'aide
pas)
Je ne sais pas. Je me sers regulièrement des classes assez
complexes dans les objets dynamiques. Typiquement,
d'ailleurs, ce que j'exporte est une classe d'interface :
que des fonctions virtuelles pûres. L'objet dynamique
contient une fonction usine pour les créer, et le code
utilisateur ne voit jamais de membres donnés ni de fonction
directement. Dans la pratique, ça permet de compiler avec
des options différentes aussi. (Note qu'avec cette solution,
dans son cas, le map n'apparaîtra que dans la DLL.)
Je suis absolument d'accord et je le fais souvent car une
classe d'interface n'exprime qu'un contrat et ne pollue pas le
client. Les usines sont aussi un composant essentiel; les
objets que je crée avec sont détruits à coup de 'delete this'
et ils ont tous un destructeur inaccessible au code client (y
compris les interfaces, il n'y a pas de destructeur virtuel
dans ce cas).
kanze a écrit:
Je vois déjà un problème ici. Ce typedef, en réalité,
peut représenter PLUSIEURS types.
Oui et non. En tant que type, c'est bien un seul type. En
revanche, il est clair qu'il faut que tous les objets linkés
dans le programme (qu'ils soient linké dynamiquement ou
statiquement) soit compilés avec le même compilateur et les
mêmes options. Qu'on ait une version débug dans un des
fichiers objets et une version optimisée dans un autre, et
il y a des chances que ça ne marche pas.
J'en suis conscient, je me suis assez cassé les dents dessus.
Aussi, il faut faire gaffe en ce qui concerne les parties
qui dépendent des objets statiques -- dans le cas d'un map,
par exemple, l'allocateur (qui utilise une structure
statique pour gérer la memoire). Il ne faut pas qu'ils
utilisent une instance une fois, et une autre instance une
autre fois. Ce qui correspond à des options par défaut sous
Unix, mais qui, d'après ce que j'ai entendu dire, n'est pas
le défaut sous Unix.
J'essaie de ne pas avoir d'objets statiques dans mes modules.
Pour l'instant j'en ai jamais eu besoin. J'allume un cierge.
[...]
Et dans six mois ? Il faut recompiler les 50 modules car on a
une nouvelle version du compilateur ?
Pas simplement en tous cas.. là, je dois partir maintenant.
Mais juste un conseil: utiliser des POD, pas des classes.
(et surtout qu'en plus ce sont des templates ce qui n'aide
pas)
Je ne sais pas. Je me sers regulièrement des classes assez
complexes dans les objets dynamiques. Typiquement,
d'ailleurs, ce que j'exporte est une classe d'interface :
que des fonctions virtuelles pûres. L'objet dynamique
contient une fonction usine pour les créer, et le code
utilisateur ne voit jamais de membres donnés ni de fonction
directement. Dans la pratique, ça permet de compiler avec
des options différentes aussi. (Note qu'avec cette solution,
dans son cas, le map n'apparaîtra que dans la DLL.)
Je suis absolument d'accord et je le fais souvent car une
classe d'interface n'exprime qu'un contrat et ne pollue pas le
client. Les usines sont aussi un composant essentiel; les
objets que je crée avec sont détruits à coup de 'delete this'
et ils ont tous un destructeur inaccessible au code client (y
compris les interfaces, il n'y a pas de destructeur virtuel
dans ce cas).
kanze a écrit:Je vois déjà un problème ici. Ce typedef, en réalité,
peut représenter PLUSIEURS types.
Oui et non. En tant que type, c'est bien un seul type. En
revanche, il est clair qu'il faut que tous les objets linkés
dans le programme (qu'ils soient linké dynamiquement ou
statiquement) soit compilés avec le même compilateur et les
mêmes options. Qu'on ait une version débug dans un des
fichiers objets et une version optimisée dans un autre, et
il y a des chances que ça ne marche pas.
J'en suis conscient, je me suis assez cassé les dents dessus.
Aussi, il faut faire gaffe en ce qui concerne les parties
qui dépendent des objets statiques -- dans le cas d'un map,
par exemple, l'allocateur (qui utilise une structure
statique pour gérer la memoire). Il ne faut pas qu'ils
utilisent une instance une fois, et une autre instance une
autre fois. Ce qui correspond à des options par défaut sous
Unix, mais qui, d'après ce que j'ai entendu dire, n'est pas
le défaut sous Unix.
J'essaie de ne pas avoir d'objets statiques dans mes modules.
Pour l'instant j'en ai jamais eu besoin. J'allume un cierge.
[...]
Et dans six mois ? Il faut recompiler les 50 modules car on a
une nouvelle version du compilateur ?
Pas simplement en tous cas.. là, je dois partir maintenant.
Mais juste un conseil: utiliser des POD, pas des classes.
(et surtout qu'en plus ce sont des templates ce qui n'aide
pas)
Je ne sais pas. Je me sers regulièrement des classes assez
complexes dans les objets dynamiques. Typiquement,
d'ailleurs, ce que j'exporte est une classe d'interface :
que des fonctions virtuelles pûres. L'objet dynamique
contient une fonction usine pour les créer, et le code
utilisateur ne voit jamais de membres donnés ni de fonction
directement. Dans la pratique, ça permet de compiler avec
des options différentes aussi. (Note qu'avec cette solution,
dans son cas, le map n'apparaîtra que dans la DLL.)
Je suis absolument d'accord et je le fais souvent car une
classe d'interface n'exprime qu'un contrat et ne pollue pas le
client. Les usines sont aussi un composant essentiel; les
objets que je crée avec sont détruits à coup de 'delete this'
et ils ont tous un destructeur inaccessible au code client (y
compris les interfaces, il n'y a pas de destructeur virtuel
dans ce cas).
Manuel Zaccaria wrote on 20/07/2006 00:36:[...]
Je suis absolument d'accord et je le fais souvent car une classe
d'interface n'exprime qu'un contrat et ne pollue pas le client.
Les usines sont aussi un composant essentiel; les objets que
je crée avec sont détruits à coup de 'delete this' et ils ont
tous un destructeur inaccessible au code client (y compris les
interfaces, il n'y a pas de destructeur virtuel dans ce cas).
des dll basées sur une interface publique, une gestion mémoire
confinée à la librairie (notamment un public dispose(){delete
this;}) et des factory statiques permettent d'obtenir du code
prédictif et stable (nombre d'architecture marshalées
fonctionnent comme cela).
les simples changements de compilo ne condamment pas à la
recompil globale (seuls des basiques comme la convention
d'appel (M$ spécifique?) ou la taille d'un int (32 ou 64)
devront évidemment être constants).
Manuel Zaccaria wrote on 20/07/2006 00:36:
[...]
Je suis absolument d'accord et je le fais souvent car une classe
d'interface n'exprime qu'un contrat et ne pollue pas le client.
Les usines sont aussi un composant essentiel; les objets que
je crée avec sont détruits à coup de 'delete this' et ils ont
tous un destructeur inaccessible au code client (y compris les
interfaces, il n'y a pas de destructeur virtuel dans ce cas).
des dll basées sur une interface publique, une gestion mémoire
confinée à la librairie (notamment un public dispose(){delete
this;}) et des factory statiques permettent d'obtenir du code
prédictif et stable (nombre d'architecture marshalées
fonctionnent comme cela).
les simples changements de compilo ne condamment pas à la
recompil globale (seuls des basiques comme la convention
d'appel (M$ spécifique?) ou la taille d'un int (32 ou 64)
devront évidemment être constants).
Manuel Zaccaria wrote on 20/07/2006 00:36:[...]
Je suis absolument d'accord et je le fais souvent car une classe
d'interface n'exprime qu'un contrat et ne pollue pas le client.
Les usines sont aussi un composant essentiel; les objets que
je crée avec sont détruits à coup de 'delete this' et ils ont
tous un destructeur inaccessible au code client (y compris les
interfaces, il n'y a pas de destructeur virtuel dans ce cas).
des dll basées sur une interface publique, une gestion mémoire
confinée à la librairie (notamment un public dispose(){delete
this;}) et des factory statiques permettent d'obtenir du code
prédictif et stable (nombre d'architecture marshalées
fonctionnent comme cela).
les simples changements de compilo ne condamment pas à la
recompil globale (seuls des basiques comme la convention
d'appel (M$ spécifique?) ou la taille d'un int (32 ou 64)
devront évidemment être constants).
Je me retrouve très souvent dans le cas où j'ai des plug-ins
qui utilisent une infrastructure commune. Et bien, je me
retrouve souvent obligé de mettre cette architecture dans une
DLL aussi, car sinon, la mémoire globale (et donc les
singletons) gérée pas cette bibliothèque se trouve dupliquée
par DLL de plug-in, ce qui n'est pas sans poser de problèmes.
Autre cas d'utilisation de DLL : .NET... Il n'y a pas de
linker avec ce framework, et tout passe donc par des
bibliothèques dynamiques :(
Je ne suis pas sûr de comprendre. Sous Unix, et sous les Windows
classiques pré-.NET, il n'y a pas de bibliothèques dynamiques ;
malgré leur nom, une DLL se comporte comme un fichier objet en
partie pré-linké.
Et il faut bien quelque chose du genre d'un
éditeur de liens pour les construire. (Sous Unix, c'est bien
l'éditeur de liens classique, ld, qui le fait. J'ai l'impression
que c'est aussi ce qui se passe quand je donne l'option /LD à
cl : il invoque link avec l'option /DLL.)
Ou est-ce que .NET fonctionne un peu comme Java, où les fichiers
.jar sont réelement des bibliothèques, et que les composants en
sont réelement extraits et linkés lors de l'exécution, sans
jamais avoir été linkés entre eux avant ? (C'est un des grands
défauts de Java, qui fait qu'on ne peut pas s'en servir dans
certaines applications, où la sécurité ou la fiabilité sont
des critères importants.)
Je me retrouve très souvent dans le cas où j'ai des plug-ins
qui utilisent une infrastructure commune. Et bien, je me
retrouve souvent obligé de mettre cette architecture dans une
DLL aussi, car sinon, la mémoire globale (et donc les
singletons) gérée pas cette bibliothèque se trouve dupliquée
par DLL de plug-in, ce qui n'est pas sans poser de problèmes.
Autre cas d'utilisation de DLL : .NET... Il n'y a pas de
linker avec ce framework, et tout passe donc par des
bibliothèques dynamiques :(
Je ne suis pas sûr de comprendre. Sous Unix, et sous les Windows
classiques pré-.NET, il n'y a pas de bibliothèques dynamiques ;
malgré leur nom, une DLL se comporte comme un fichier objet en
partie pré-linké.
Et il faut bien quelque chose du genre d'un
éditeur de liens pour les construire. (Sous Unix, c'est bien
l'éditeur de liens classique, ld, qui le fait. J'ai l'impression
que c'est aussi ce qui se passe quand je donne l'option /LD à
cl : il invoque link avec l'option /DLL.)
Ou est-ce que .NET fonctionne un peu comme Java, où les fichiers
.jar sont réelement des bibliothèques, et que les composants en
sont réelement extraits et linkés lors de l'exécution, sans
jamais avoir été linkés entre eux avant ? (C'est un des grands
défauts de Java, qui fait qu'on ne peut pas s'en servir dans
certaines applications, où la sécurité ou la fiabilité sont
des critères importants.)
Je me retrouve très souvent dans le cas où j'ai des plug-ins
qui utilisent une infrastructure commune. Et bien, je me
retrouve souvent obligé de mettre cette architecture dans une
DLL aussi, car sinon, la mémoire globale (et donc les
singletons) gérée pas cette bibliothèque se trouve dupliquée
par DLL de plug-in, ce qui n'est pas sans poser de problèmes.
Autre cas d'utilisation de DLL : .NET... Il n'y a pas de
linker avec ce framework, et tout passe donc par des
bibliothèques dynamiques :(
Je ne suis pas sûr de comprendre. Sous Unix, et sous les Windows
classiques pré-.NET, il n'y a pas de bibliothèques dynamiques ;
malgré leur nom, une DLL se comporte comme un fichier objet en
partie pré-linké.
Et il faut bien quelque chose du genre d'un
éditeur de liens pour les construire. (Sous Unix, c'est bien
l'éditeur de liens classique, ld, qui le fait. J'ai l'impression
que c'est aussi ce qui se passe quand je donne l'option /LD à
cl : il invoque link avec l'option /DLL.)
Ou est-ce que .NET fonctionne un peu comme Java, où les fichiers
.jar sont réelement des bibliothèques, et que les composants en
sont réelement extraits et linkés lors de l'exécution, sans
jamais avoir été linkés entre eux avant ? (C'est un des grands
défauts de Java, qui fait qu'on ne peut pas s'en servir dans
certaines applications, où la sécurité ou la fiabilité sont
des critères importants.)
Je ne suis pas sûr de comprendre. Sous Unix, et sous les Windows
classiques pré-.NET, il n'y a pas de bibliothèques dynamiques ;
malgré leur nom, une DLL se comporte comme un fichier objet en
partie pré-linké.
Par focément. On peut se lier statiquement avec une DLL, par
l'intermédiaire par exemple d'un .lib d'import, mais on peut aussi s'y
lier dynamiquement (avec des fonction LoadLibrary, GetProcAdress...).
Et il faut bien quelque chose du genre d'un
éditeur de liens pour les construire. (Sous Unix, c'est bien
l'éditeur de liens classique, ld, qui le fait. J'ai l'impression
que c'est aussi ce qui se passe quand je donne l'option /LD à
cl : il invoque link avec l'option /DLL.)
Ou est-ce que .NET fonctionne un peu comme Java, où les fichiers
.jar sont réelement des bibliothèques, et que les composants en
sont réelement extraits et linkés lors de l'exécution, sans
jamais avoir été linkés entre eux avant ? (C'est un des grands
défauts de Java, qui fait qu'on ne peut pas s'en servir dans
certaines applications, où la sécurité ou la fiabilité sont
des critères importants.)
Les DLL externes sont utilisée à l'exécution, bien évidemment, mais
aussi à la compilation, où elles ont pour seul(*) but de permettre par
de l'introspection de publier leur contenu, remplaçant ainsi les .h.
Donc, il n'y a pas un module par fichier ou par classe obligatoirement,
mais les modules on tendance à être assez petits si on veut faire du
code réutilisable, et il manque un outil permettant de packager
plusieurs modules en un seul, afin d'éviter les problèmes d'installation.
Je ne suis pas sûr de comprendre. Sous Unix, et sous les Windows
classiques pré-.NET, il n'y a pas de bibliothèques dynamiques ;
malgré leur nom, une DLL se comporte comme un fichier objet en
partie pré-linké.
Par focément. On peut se lier statiquement avec une DLL, par
l'intermédiaire par exemple d'un .lib d'import, mais on peut aussi s'y
lier dynamiquement (avec des fonction LoadLibrary, GetProcAdress...).
Et il faut bien quelque chose du genre d'un
éditeur de liens pour les construire. (Sous Unix, c'est bien
l'éditeur de liens classique, ld, qui le fait. J'ai l'impression
que c'est aussi ce qui se passe quand je donne l'option /LD à
cl : il invoque link avec l'option /DLL.)
Ou est-ce que .NET fonctionne un peu comme Java, où les fichiers
.jar sont réelement des bibliothèques, et que les composants en
sont réelement extraits et linkés lors de l'exécution, sans
jamais avoir été linkés entre eux avant ? (C'est un des grands
défauts de Java, qui fait qu'on ne peut pas s'en servir dans
certaines applications, où la sécurité ou la fiabilité sont
des critères importants.)
Les DLL externes sont utilisée à l'exécution, bien évidemment, mais
aussi à la compilation, où elles ont pour seul(*) but de permettre par
de l'introspection de publier leur contenu, remplaçant ainsi les .h.
Donc, il n'y a pas un module par fichier ou par classe obligatoirement,
mais les modules on tendance à être assez petits si on veut faire du
code réutilisable, et il manque un outil permettant de packager
plusieurs modules en un seul, afin d'éviter les problèmes d'installation.
Je ne suis pas sûr de comprendre. Sous Unix, et sous les Windows
classiques pré-.NET, il n'y a pas de bibliothèques dynamiques ;
malgré leur nom, une DLL se comporte comme un fichier objet en
partie pré-linké.
Par focément. On peut se lier statiquement avec une DLL, par
l'intermédiaire par exemple d'un .lib d'import, mais on peut aussi s'y
lier dynamiquement (avec des fonction LoadLibrary, GetProcAdress...).
Et il faut bien quelque chose du genre d'un
éditeur de liens pour les construire. (Sous Unix, c'est bien
l'éditeur de liens classique, ld, qui le fait. J'ai l'impression
que c'est aussi ce qui se passe quand je donne l'option /LD à
cl : il invoque link avec l'option /DLL.)
Ou est-ce que .NET fonctionne un peu comme Java, où les fichiers
.jar sont réelement des bibliothèques, et que les composants en
sont réelement extraits et linkés lors de l'exécution, sans
jamais avoir été linkés entre eux avant ? (C'est un des grands
défauts de Java, qui fait qu'on ne peut pas s'en servir dans
certaines applications, où la sécurité ou la fiabilité sont
des critères importants.)
Les DLL externes sont utilisée à l'exécution, bien évidemment, mais
aussi à la compilation, où elles ont pour seul(*) but de permettre par
de l'introspection de publier leur contenu, remplaçant ainsi les .h.
Donc, il n'y a pas un module par fichier ou par classe obligatoirement,
mais les modules on tendance à être assez petits si on veut faire du
code réutilisable, et il manque un outil permettant de packager
plusieurs modules en un seul, afin d'éviter les problèmes d'installation.
Il vaut mieux que l'organisation de la vtable ne change pas non
plus, si tu te sers d'une interface. Ni la structure des données
passées en paramètre (par valeur ou par référence) : n'essaie
pas de passer un std::string d'une module compilée avec VC++ 6 à
une module compilée avec VC++ 2005.
N'essaie pas, d'ailleurs, de passer un std::vector<int> d'une
module compilée avec VC++ 2005 avec les options /MTd et une
autre compilée sans cette option. (Ce qui nous ramène à la
question du départ.)
Il vaut mieux que l'organisation de la vtable ne change pas non
plus, si tu te sers d'une interface. Ni la structure des données
passées en paramètre (par valeur ou par référence) : n'essaie
pas de passer un std::string d'une module compilée avec VC++ 6 à
une module compilée avec VC++ 2005.
N'essaie pas, d'ailleurs, de passer un std::vector<int> d'une
module compilée avec VC++ 2005 avec les options /MTd et une
autre compilée sans cette option. (Ce qui nous ramène à la
question du départ.)
Il vaut mieux que l'organisation de la vtable ne change pas non
plus, si tu te sers d'une interface. Ni la structure des données
passées en paramètre (par valeur ou par référence) : n'essaie
pas de passer un std::string d'une module compilée avec VC++ 6 à
une module compilée avec VC++ 2005.
N'essaie pas, d'ailleurs, de passer un std::vector<int> d'une
module compilée avec VC++ 2005 avec les options /MTd et une
autre compilée sans cette option. (Ce qui nous ramène à la
question du départ.)