Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[BCB][HS] Problème de classes partagées

13 réponses
Avatar
Michael
Bonjour à tous,

je sais que je suis HS avec ce thread, mais je n'arrive pas à avoir de
réponses ailleurs.

Ma question s'adresse aux utilisateurs de Borland C++ Builder 6.

J'ai créé plusieurs programmes qui utilisent certaines classes en commun.
J'ai placé tous ces fichiers dans un répertoire Projects\Classes communes.

Habituellement quand je modifie des fichiers dans un projet, pour constater
les changements il suffit de cliquer sur le bouton Exécuter, qui se charge
de recompiler les fichiers modifiés, de linker ceux-ci avec les fichiers
qui n'ont pas changé, et de créer l'exécutable.

Le problème se situe lorsque je modifie des fichiers communs à plusieurs
programmes.

Quand je fais exécuter, visiblement tout se passe bien, mais les
changements ne sont pas présents dans l'exécutable, et la fenêtre de
déboguage perd les pédales, puisqu'elle me met les points bleus (je sais
pas comment ça s'appelle, mais quand on clique dessus on place un point
d'arret) devant des lignes vides... Je suis donc obligé de reconstruire le
projet en entier, ce qui est évidemment beaucoup plus long...

Par contre quand je modifie des fichiers propres au projet, tout se passe
bien...

Je ne pense pas que le problème vienne des entête précompilés, j'ai tout
vérifié, et j'ai bien partout le même #include avant le #pragma hdrstop

Chaque fichier a son propre fichier entête (défini dans les options du
projet > Onglet Compilateur > Entêtes précompilés > Nom de fichier). J'ai
essayé avec le même enteête pour tous et c'est pareil....


Donc en gros ma question est: comment procédez-vous quand vous devez
utiliser les mêmes classes dans plusieurs projets?

J'espère avoir été clair

Merci d'avance

Mike

10 réponses

1 2
Avatar
Alexandre
bonjour,


Donc en gros ma question est: comment procédez-vous quand vous devez
utiliser les mêmes classes dans plusieurs projets?


je les mets dans des dll (des paquets bcb par exemple), en tout cas dans du
code compilé à part. Ce qui t'évite le problème que tu indiques. Bien sûr si
tu modifies ta classe partagée il faut recréer ton paquet, mais tu n'as même
pas besoin de recompiler les projets (à moins que tu ne changes les
spécifications, l'interface, de tes classe partagées). En plus ça t'évite
d'avoir 250x le même code dans des projets différents...


J'espère avoir été clair

Merci d'avance

Mike


Avatar
Michael
"Alexandre" wrote in
news:41f69fda$0$22651$:

bonjour,


Donc en gros ma question est: comment procédez-vous quand vous devez
utiliser les mêmes classes dans plusieurs projets?


je les mets dans des dll (des paquets bcb par exemple), en tout cas
dans du code compilé à part. Ce qui t'évite le problème que tu
indiques. Bien sûr si tu modifies ta classe partagée il faut recréer
ton paquet, mais tu n'as même pas besoin de recompiler les projets (à
moins que tu ne changes les spécifications, l'interface, de tes classe
partagées). En plus ça t'évite d'avoir 250x le même code dans des
projets différents...


J'espère avoir été clair

Merci d'avance

Mike






Bonsoir,

aurais-tu des infos sur la manière de compiler tout le code commun dans des
paquets?

C'est une chose que je n'ai encore jamais fait.

Une fois que le code est dans un paquet, et qu'on le lie au projet en
cours, est-ce que c'est un paquet à distribuer en plus de l'EXE ou bien
est-il imbriqué dans l'EXE?

Jusqu'à maintenant j'ai réussi à créer des composants, mais pas des
paquets...


Merci d'avance...

Mike


Avatar
Michael
"Alexandre" wrote in
news:41f69fda$0$22651$:

En plus ça t'évite d'avoir 250x le même code dans des
projets différents...


En quoi ça évite d'avoir le même code? Là j'avoue que je ne vois pas...

Avatar
Alexandre
"Michael" a écrit dans le message de
news:
"Alexandre" wrote in
news:41f69fda$0$22651$:

En plus ça t'évite d'avoir 250x le même code dans des
projets différents...


En quoi ça évite d'avoir le même code? Là j'avoue que je ne vois pas...
la DLL n'est chargée d'une fois en mémoire, présente une seule fois sur le

disque, etc...


Avatar
Michael
En plus ça t'évite d'avoir 250x le même code dans des
projets différents...


En quoi ça évite d'avoir le même code? Là j'avoue que je ne vois
pas...
la DLL n'est chargée d'une fois en mémoire, présente une seule fois

sur le disque, etc...



Effectivement, je n'avais pas vu le "dans des projets différents" de ton
post...

Sinon je me pose la question suivante: je ne veux pas que le code que je
voudrais partager soit dans une DLL. Je peux choisir de le compiler
uniquement dans un .LIB?

Sinon une question:

soit la DLL A (donc avec A.LIB)
soit la DLL B (avec B.LIB) qui nécéssite A.DLL, j'ajoute donc A.lib au
projet B

Soit l'EXE qui utilise ces deux DLL. Est-ce que l'ajout des .lib se fait
uniquement ici, ou bien chaque DLL doit importer les LIB dont elle a
besoin?



Avatar
Alexandre
bonjour,

Effectivement, je n'avais pas vu le "dans des projets différents" de ton
post...

Sinon je me pose la question suivante: je ne veux pas que le code que je
voudrais partager soit dans une DLL. Je peux choisir de le compiler
uniquement dans un .LIB?


oui, mais dans ce cas tu vas le lier statiquement à chaque projet, ie il
sera dupliqué, et une re-construction du projet est nécessaire (au moins la
phase d'éditions de liens)


Sinon une question:

soit la DLL A (donc avec A.LIB)
soit la DLL B (avec B.LIB) qui nécéssite A.DLL, j'ajoute donc A.lib au
projet B

Soit l'EXE qui utilise ces deux DLL. Est-ce que l'ajout des .lib se fait
uniquement ici, ou bien chaque DLL doit importer les LIB dont elle a
besoin?


je ne me suis jamais posé la question, mais à priori tu n'as besoin
d'inclure A.lib qu'au projet B, si ton exe n'utilise que B (et A
indirectement mais sans appeler de fonctions de A). par contre, si ton exe
appelles directement une fonction de A, alors A.lib devra être inclus dans
ton projet.

Avatar
Pierre Maurette
[...]
Sinon je me pose la question suivante: je ne veux pas que le code que je
voudrais partager soit dans une DLL. Je peux choisir de le compiler
uniquement dans un .LIB?
Justement, les paquets .bpl sont faits pour vous. Ce sont des DLL

proposant la possibilité d'être également liables statiquement. Selon
vos choix qui peuvent changer au cours de la génèse du projet jusqu'au
déploiement, vous décidez en un clic de rongeur dans
Projets->Options...->Paquets

Une logique voudrait que vous réserviez les .lib et .dll à des fonctions
et classes standard utilisables en dehors de BCB et les .bpl à celles
qui ne le sont pas. A ceci près qu'un paquet .bcl de fontions et classes
standards reste plus pratique (le clic de rongeur, voir plus haut) dans
le cadre d'un travail BCB.

Sauf si j'ai mal cherché et sauf à éditer le makefile, la notion de
projet multicible n'existe pas sous BCB. Mais Fichier->Nouveau offre
d'autres possibilités. Dans un "groupe de projets", vous ajoutez un
projet "Expert DLL", un projet "Bibliothèque" et un projet "Paquet".
Vous créez ou copiez vos "Unités" de code utile, fonctions et/ou
classes. Vous ajoutez ces unités aux trois projets. Vous ajoutez au
groupe de projets des applications de test (je ne pense pas qu'une seule
suffise à cause des conflits de noms). Ça doit le faire.
Eventuellement vous pouvez dans chacun des trois projets lib, dll et bpl
aller dans Projets->Options...->Répertoires/Conditions et définir
repectivement _FORLIB, _FORDLL et _FORBPL pour faire un peu de #ifdef.

Bon, je n'ai jamais fait une telle usine à gaz, ayant soit besoin d'un
.bpl pour la réutilisation, soit d'une DLL parce que j'ai besoin d'une
DLL, mais ça doit marcher (en tous cas, ça construit).


Sinon une question:

soit la DLL A (donc avec A.LIB)
soit la DLL B (avec B.LIB) qui nécéssite A.DLL, j'ajoute donc A.lib au
projet B

Soit l'EXE qui utilise ces deux DLL. Est-ce que l'ajout des .lib se fait
uniquement ici, ou bien chaque DLL doit importer les LIB dont elle a
besoin?
Je dirais comme Alexandre. Si vous ne liez à EXE que des objets de B,

seul B.LIB est nécessaire. A.LIB ne sert qu'au moment de la construction
(édition de lien sauf erreur de ma part) de B.DLL.

--
Pierre

Avatar
Michael
Sauf si j'ai mal cherché et sauf à éditer le makefile, la notion de
projet multicible n'existe pas sous BCB. Mais Fichier->Nouveau offre
d'autres possibilités. Dans un "groupe de projets", vous ajoutez un
projet "Expert DLL", un projet "Bibliothèque" et un projet "Paquet".
Vous créez ou copiez vos "Unités" de code utile, fonctions et/ou
classes. Vous ajoutez ces unités aux trois projets. Vous ajoutez au
groupe de projets des applications de test (je ne pense pas qu'une
seule suffise à cause des conflits de noms). Ça doit le faire.
Eventuellement vous pouvez dans chacun des trois projets lib, dll et
bpl aller dans Projets->Options...->Répertoires/Conditions et définir
repectivement _FORLIB, _FORDLL et _FORBPL pour faire un peu de #ifdef.

Bon, je n'ai jamais fait une telle usine à gaz, ayant soit besoin d'un
.bpl pour la réutilisation, soit d'une DLL parce que j'ai besoin d'une
DLL, mais ça doit marcher (en tous cas, ça construit).


C'est ce que j'ai fait avec les .LIB

J'ai créé un groupe de projets avec en premier lieu tous mes .LIB.

Tout en bas il y a mes deux projets qui utilisent les .LIB.

Par contre j'ai pas compris les _FORLIB, _FORDLL...

Par contre une question: quand je modifie l'implémentation d'une classe
d'un .LIB, je dois uniquement recompiler le .LIb et pas les EXE qui
l'utilisent, c'est bien ça?

Par contre si je change l'interface, je dois bien recompiler les deux?

Avatar
Pierre Maurette
[...]
C'est ce que j'ai fait avec les .LIB

J'ai créé un groupe de projets avec en premier lieu tous mes .LIB.

Tout en bas il y a mes deux projets qui utilisent les .LIB.

Par contre j'ai pas compris les _FORLIB, _FORDLL...
Il y a dans chaque projet du groupe un .cpp spécifique, en particulier

celui qui contient le DllEntryPoint() dans le .dll et le .bpl. Mais le
but est de n'avoir qu'une version des fonctions et classes "utiles". Il
est possible qu'il faille faire quelques ajustements du code en fonction
de la cible (je n'en sais rien). Chaque unité sera compilée 3 fois, une
fois pour chaque cible. Par les _FORLIB, _FORDLL... (tout comme le
_DEBUG), le compilateur (le préprocesseur) saura quelle est la cible:

#if defined(_FORLIB)
AnsiString ErrorMessage1 = "Errreur dans F1 de la bib";
#elif defined(_FORBPL)
AnsiString ErrorMessage1 = "Errreur dans F1 de le paquet";
#elif defined(_FORDLL)
AnsiString ErrorMessage1 = "Errreur dans F1 de la dll";
#else
// Gasp !
#endif

Par contre une question: quand je modifie l'implémentation d'une classe
d'un .LIB, je dois uniquement recompiler le .LIb et pas les EXE qui
l'utilisent, c'est bien ça?

Par contre si je change l'interface, je dois bien recompiler les deux?
Attention au terme compiler. Il faut distinguer compiler, lier et

construire (compiler et lier). Sous BCB, vous compilez parfois (pour
vérifier la syntaxe, en général, je sais, c'est pas bô, mais c'est ce
que je fais ;-)), mais le plus souvent vous construisez. En fait,
construire est équivalent à lancer un make.
Ici, qu'il s'agisse d'un .dll ou d'un .lib, il suffirait de lier. Mais
en cas de modification de l'interface, il me semble qu'au moins un .cpp
ou un .h sera modifié. Parlons donc de construire.

Ce que vous dites serait exact pour un .dll. Pour un .lib, étant entendu
qu'il s'agit d'une bibliothèque à liaison statique, il faut reconstruire
dans tous les cas. Un .lib est très proche d'un .obj, c'est à dire du
code machine non entièrement résolu (non lié). Il est ajouté aux autres
.obj par le lieur pour obtenir le .exe. Il faut donc au moins lier dans
tous les cas.

--
Pierre

Avatar
Michael
Par contre j'ai pas compris les _FORLIB, _FORDLL...
Il y a dans chaque projet du groupe un .cpp spécifique, en particulier

celui qui contient le DllEntryPoint() dans le .dll et le .bpl. Mais le
but est de n'avoir qu'une version des fonctions et classes "utiles". Il
est possible qu'il faille faire quelques ajustements du code en fonction
de la cible (je n'en sais rien). Chaque unité sera compilée 3 fois, une
fois pour chaque cible. Par les _FORLIB, _FORDLL... (tout comme le
_DEBUG), le compilateur (le préprocesseur) saura quelle est la cible:

#if defined(_FORLIB)
AnsiString ErrorMessage1 = "Errreur dans F1 de la bib";
#elif defined(_FORBPL)
AnsiString ErrorMessage1 = "Errreur dans F1 de le paquet";
#elif defined(_FORDLL)
AnsiString ErrorMessage1 = "Errreur dans F1 de la dll";
#else
// Gasp !
#endif



OK, ça roule, j'ai bien compris...

Par contre une question: quand je modifie l'implémentation d'une classe
d'un .LIB, je dois uniquement recompiler le .LIb et pas les EXE qui
l'utilisent, c'est bien ça?

Par contre si je change l'interface, je dois bien recompiler les deux?
Attention au terme compiler. Il faut distinguer compiler, lier et

construire (compiler et lier). Sous BCB, vous compilez parfois (pour
vérifier la syntaxe, en général, je sais, c'est pas bô, mais c'est ce
que je fais ;-)), mais le plus souvent vous construisez. En fait,
construire est équivalent à lancer un make.
Ici, qu'il s'agisse d'un .dll ou d'un .lib, il suffirait de lier. Mais
en cas de modification de l'interface, il me semble qu'au moins un .cpp
ou un .h sera modifié. Parlons donc de construire.

Ce que vous dites serait exact pour un .dll. Pour un .lib, étant entendu
qu'il s'agit d'une bibliothèque à liaison statique, il faut reconstruire
dans tous les cas. Un .lib est très proche d'un .obj, c'est à dire du
code machine non entièrement résolu (non lié). Il est ajouté aux autres
.obj par le lieur pour obtenir le .exe. Il faut donc au moins lier dans
tous les cas.



J'ai eu le temps de tester tout ça aujourd'hui, et effectivement quand on
recompile un .LIB, il faut lier l'EXE l'utilisant...

Merci pour toutes ces infos...


1 2