LES DLLS SOUS VB6

bouv Messages postés 1411 Date d'inscription mercredi 6 août 2003 Statut Membre Dernière intervention 3 mars 2019 - 16 juin 2005 à 16:26
cs_cyrilp Messages postés 140 Date d'inscription mercredi 4 octobre 2000 Statut Membre Dernière intervention 12 août 2009 - 16 oct. 2006 à 20:08
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/32111-les-dlls-sous-vb6

cs_cyrilp Messages postés 140 Date d'inscription mercredi 4 octobre 2000 Statut Membre Dernière intervention 12 août 2009
16 oct. 2006 à 20:08
Mouais...

Dans les règles de l'art du développement, il est préférable de ne jamais casser une interface. Par exemple, j'ai créé une classe "cTest" dans ma DLL ActiveX "DllTest.dll". Si je créé une fonction publique "TEST", une fois compilé, il ne faut plus supprimer cette fonction, ou modifier le type et le nombre de ses paramètres.

Une fois ces postulats respectés, il suffit de compiler en "compatibilité binaire" et il n'y aura plus jamais de problème et la liaison précoce peut être utilisée !!!
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
27 oct. 2005 à 14:47
Voilou, c'est fait.
Si ça se voit pas encore, c'est encore la faute à la mise en cache.
Bah le source est maintenant proche du néant.
Par contre, je me suis appliqué sur la description !

Warny,
J'ai eu pas mal de problèmes pour l'interface...
En plus des bugs et autres messages d'erreur habituel, je crois que VB6 a refusé que la déclaration des implémentations diffères de celle des interfaces. J'avais mis aucun type dans l'interface, long dans une implémentation, et integer dans la dernière.
N'empèche, 3 classes, ça commence à faire beaucoup, même si on les regroupe.
Bilan, j'ai retiré l'exemple d'interface de mon source. C'est vrai que la surcharge des opérateurs peut être parfois bien pratique, mais là, c'est un peu lourd. Désolé.
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
17 oct. 2005 à 18:50
OK, je vais faire ça aussi.
cs_Warny Messages postés 473 Date d'inscription mercredi 7 août 2002 Statut Membre Dernière intervention 10 juin 2015
17 oct. 2005 à 18:41
L'implémentation serait choisi au moment de l'execution. Tout l'interêt est là.
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
17 oct. 2005 à 18:39
La seule différence entre ces deux logiciels serait la dll d'implémentation, c'est ça ?

Ou alors, est ce que l'implémentatons est choisie au moment de l'execution ?
cs_Warny Messages postés 473 Date d'inscription mercredi 7 août 2002 Statut Membre Dernière intervention 10 juin 2015
17 oct. 2005 à 10:12
Elle permet justement de faire une boite à outil.
Il s'agit principalement de la création de classe ayant la même interface (càd: implémentant la même classe).
si MyInterface est mon interface de base
et si :
-MyClass1
-MyClass2
sont deux classe implémentant MyInterface, tu peux appeler l'une ou l'autre indiféremment.
Par exemple faire un lecteur de fichier texte csv et un autre pour les champs à largeur fixes.
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
17 oct. 2005 à 10:04
Ouaich pour la compilation, mais je sais pas ce qu'est une boîte à outil...

Je vois pas ce que ta méthode fait de plus (deux dlls pour une dll d'interface ?).
cs_Warny Messages postés 473 Date d'inscription mercredi 7 août 2002 Statut Membre Dernière intervention 10 juin 2015
17 oct. 2005 à 10:00
Le mettre à jour et expliquer comment fonctionne la compilation de dll, éventuellement, expliquer comment upgrader une dll ou comment faire une boite à outil extensible.
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
17 oct. 2005 à 09:57
Pardon, c'tait ici l'ERRATUM. Le CLSID change effectivement à chaque compilation (Comment j'ai fait pour pas le voir ?????) Désolé.

Je sais plus trops quoi faire de ce source...
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
13 oct. 2005 à 17:02
Je suis tout à fait d'accord avec toi rt15 : tu veux modifier complètement une fonction de ta dll pour qu'elle fasse des choses totalement différentes ? Alors pourquoi ne pas faire une fonction à part avec un nom différent ? Car si tu ne fait pas comme cà, tu es obligé d'abandonner la compatibilité, et là, tout tes clients sont hyper content : ils ne peuvent plus utiliser ta dll car l'appel à la fonction plante avec la nouvelle version de la dll.

Microsoft l'a bien compris en gardant les fonctions obsolètes tout de même opérationnelles depuis Windows 95 ! (ils vont quand même en supprimer pas mal pour le passage à Vista apparement).

DarK Sidious
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
13 oct. 2005 à 16:39
A mon avis, il vaut mieux faire comme Windows !

LoadLibrary n'était plus sastisfaisante.

Alors ils ont fait LoadLibraryEx qui prend des arguments différents.

Et transformer la routine LoadLibrary en un appel de loadlibraryEx en transmettant et complètant les arguments!

A mon avis, donc, il vaux mieux créer une nouvelle fonction que prendre des risques d'incompatibilité.
cs_Patrice99 Messages postés 1221 Date d'inscription jeudi 23 août 2001 Statut Membre Dernière intervention 9 septembre 2018
13 oct. 2005 à 16:30
Si on corrige des bugs ou si on ajoute des fonctions, il est intéressant de conserver la compatibilité binaire, car qui peut le plus peut le moins, effectivement. Par contre, si on décide de ne plus implémenter une fonction ou bien de changer la logique métier (par exemple la fonction "Operation" va faire autre chose maintenant), alors dans ce cas il ne faut pas conserver la compatibilité binaire, afin de s'assurer que personne n'utilise la dll à mauvais escient.
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
13 oct. 2005 à 16:07
Je suis sur deux échanges houleux en même temps !

En mode sans compatibilité on ne perd pas le CLSID.

Je crois avoir passé suffisament de temps dans ma base de registre pour le savoir.
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
13 oct. 2005 à 15:48
Ah non, un ajout d'une fonction publique conserve la compatibilité (heureusement d'ailleurs, qui peut le plus peut le moins !), par contre, une suppression ou une modification dans le prototype d'une fonction publique existante, là oui, tu perds la compatibilité !

DarK Sidious
cs_Warny Messages postés 473 Date d'inscription mercredi 7 août 2002 Statut Membre Dernière intervention 10 juin 2015
13 oct. 2005 à 15:40
Darksidious -> la méthode est beaucoup plus utilisée que tu le penses. Les objets iads en sont une bonne preuve (ils sont programmés en C je sais... mais le principe y est)
La méthode sert surtout à faire des boites à outils, comme en vrai objet... (vive le .net)

RT15 -> en mode sans compatibilité tu perds bien le ClsID. Tout ajout d'une fonction publique à ta dll le fait perdre aussi d'ailleur.
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
13 oct. 2005 à 15:31
Il me semble que non : l'ancien CLSID est conservé (pour l'ancienne dll), par contre, un nouveau CLSID est crée pour la nouvelle dll !

Donc je te raconte pas à quoi ressemble le registre lorsque tu compile une dizaine de fois des ActiveX avec une dizaine de classe publiques en mode sans compatibilité !

DarK Sidious
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
13 oct. 2005 à 15:28
Warny,

C'est vrai que je vois plus trops l'intérêt de cette méthode. J'ai entendu dire qu'elle permet de faire passer des arguments de types différents de ceux qui étaient prévu ou je sais plus trops quoi. Mais elle est quand même très lourde à mettre en oeuvre.

DARKSIDIOUS,

En mode sans compatibilité, le CLSID est conservé, comme en mode compatibilité binaire.
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
13 oct. 2005 à 15:15
Oui, c'est le principe "d'héritage" de vb6, c'est pratique, mais très peu utilisée j'ai l'impression (perso, j'utilise pas, et j'ai très rarement vu un code utilisant les implements !).

DarK Sidious
cs_Warny Messages postés 473 Date d'inscription mercredi 7 août 2002 Statut Membre Dernière intervention 10 juin 2015
13 oct. 2005 à 15:04
La méthode que j'ai proposée n'a pas du tout cette utilité. Elle permet d'avoir plusieurs classes avec la même interface (signature) qui peuvent être appelées et référencées indiférement.
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
13 oct. 2005 à 15:01
Ben en fait, en mode sans compatibilité, VB ne conserve aucune référence à de prétendu ancienne version de la dll.
En mode compatibilité des projets, VB conserve une référence avec l'ancienne dll pour quelle puisse être utilisée plus facilement dans les projets qui l'exploite (sans devoir la référencer de nouveau donc), mais pas avec les exe qui l'utilise puisqu'il change le CLSID de la classe principale.
En mode compatibilité binaire, seule le contenu de la dll est modifié, le CLSID n'étant pas modifié, c'est comme si vous aviez exactement la même dll, mais avec des fonctionnalités en plus ou modifiées.

Un autre conseil : cochez l'incrémentation automatique du numéro de version pour savoir où vous en êtes dans les versions lors du déploiement de vos dll, cela évite de grande surprise (exemple : InnoSetup, mais je pense que les autres font de même) ne remplace pas les dll si elles possèdent un numéro de version égal à la dll déjà installé.

DarK Sidious
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
13 oct. 2005 à 14:34
Ce source ne sert plus à rrrrrrrriiiiiiiiiiieeeeeeeeeeeeeennnnnnnnnnnnnnnnnn.

Merci DARKSIDIOUS.

La case à cocher compatibilité binaire est dans l'onglet composant des propriétés du projet de la dll.

Je vous conseil vivement de la sélectionner.

Je suppose que cela permet de conserver les offsets des appels de fonctions constants (Le code doit donc être rangé de façon assez moche...).

Mais pourquoi qu'elle est pas coché par défaut ???????

Il faut que je remette ce source à jour, et là je suis comme un gland devant un terminal X (On peut rien en faire à part taper dessus).
bouv Messages postés 1411 Date d'inscription mercredi 6 août 2003 Statut Membre Dernière intervention 3 mars 2019 1
13 oct. 2005 à 10:02
Je connaissais pas non plus la Compatibilité binaire.

Il semblerait effectivement que la solution se trouve là. :-)

Je m'en vais essayer !
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
13 oct. 2005 à 09:54
Aïe.

"Compatibilité binaire"

Connaisssais pas !

Désolé.

Bah je vais essayer.

C'est vrai que cette histoire de recompilation d'exe était bizarre. N'empèche, la case n'est pas cochée par défaut !!!!!

Je suis un fervant utilisateur des dlls, mais cette histoire de recompilation de l'exe m'avait dégouté de celles de VB6.
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
12 oct. 2005 à 21:24
Lol, que dire de plus que ce que je t'ai dit sur le forum : compiler des dll sans aucune compatibilité ou en compatibilité des projets, et tu t'étonne après qu'il faut tout recompiler...

Donc un conseil : lorsque tu fait des dll, coche la case "Compatibilité binaire" dans les options de ton projet, et tu verra que ca marche tout de suite bien mieux pour distribuer tes dll !

Et là, tu peux oublier tes références tardives ou autres fichier batch.

DarK Sidious
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
29 juil. 2005 à 16:44
Warny, nickel ce que tu m'as donné.

J'ai pratiquement pas eu de messages d'erreurs.

Je l'ai inclus dans le source.

Pour ce que j'ai vu de cette méthode, elle est un peu lourde (2 dlls).

(on peut aussi mettre les 2 classes dans l'exe, mais je ne suis pas parvenu à n'avoir qu'une dll et un exe)

Il faut définir une fois pour toute l'interface, puis on peut compiler la dll d'implémentation et l'exe comme on veut.

Probablement la meilleur méthode si:

On souhaite une dll rapide.
On connait d'avance les fonctions dont on aurat besoin.
On veut partager la dll tout en pouvant la recompiler.

De même, je pense qu'il vaut mieux référencer si:

On souhaite une dll rapide.
On connait d'avance les fonctions dont on aurat besoin.
La dll est utilisée par un seul exe.

Ou si:

La dll sera compilée une bonne fois pour toutes.

Et enfin, il vaux mieux utiliser du Dim ... As Object avec du Createobject si:

On veut pouvoir rajouter des fonctions à la dll.
La dll sera utilisée par de multiples applications sur de multiples PC en de multiples versions.
La vitesse n'est pas primordiale.

J'allais oublier ma méthode ultime, qui est, je crois, la meilleure dans tous les cas.

Je serai ravis d'être contredis !

Si quelqu'un connait une source mieux ou veut en faire une mieux, ça m'arrengerai bien de trouver un remplaçant sur ce sujet épineux et complexe.
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
23 juil. 2005 à 10:58
Je vais voir ce que je peux faire.

Bel arrachage de cheveux en perspective!

Merci quand même Warny!
cs_Warny Messages postés 473 Date d'inscription mercredi 7 août 2002 Statut Membre Dernière intervention 10 juin 2015
21 juil. 2005 à 09:43
Aïe j'ai pas d'exemple. Voilà comment il faut faire

Class toto

Function Test() as string
'Doit être vide
End Function

Class Tutu
Implements Toto

Function Toto_Test() As string
'définition de la fonction
End Function

Class Utilisation
Sub Main()
Dim Objet as Toto
Set Objet = createObject("myDll.Tutu")

Objet.test
End sub
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
20 juil. 2005 à 14:35
Les dlls, en général, je m'en sert dans plusieurs programmes.

J'ai récupéré un bout exemple d'interface, mais avec une seule dll et je ne parviens pas à y faire fonctionner.

Warny, tu saurais pas où je peux trouver un autre exemple, ou me fournir un peu plus d'explications ?

Merci d'avance.
cs_Warny Messages postés 473 Date d'inscription mercredi 7 août 2002 Statut Membre Dernière intervention 10 juin 2015
12 juil. 2005 à 11:32
Je suppose que si tu veux rajouter une fonction, c'est pour l'utiliser, non ? Dans ce cas tu mettras à jour ton programme, ton interface et ta classe.
Sinon, tu peux rajouter autant de fonctions privées que tu veux.
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
12 juil. 2005 à 11:23
Effectivement, j'en ai entendu parler.

Si je comprend ton bout de code, il me parait très intéressant.

A ce que j'ai compris, on peux recompiler la dll où les fonctions sont implémentée, mais pas la dll interface.

Mais peut on rajouter une fonction ?
cs_Warny Messages postés 473 Date d'inscription mercredi 7 août 2002 Statut Membre Dernière intervention 10 juin 2015
12 juil. 2005 à 10:47
En réalité pour être compatible il faut créer une dll vide de code avec les interfaces des objets (les déclarations des objets des fonctions sans implémentation) et les implémenter dans une autre dll (grâce au mot clef Implements).
Si MyClass implémente MyInterface je peut faire :

Dim MyObject as MyInterface
set MyObject = createObject("MyDll.MyClass")

Et magie, je peux utiliser une dll indiférenciée avec une liaison précoce.
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
12 juil. 2005 à 10:41
Warny, merci pour tes explications, même si elle ne sont pas tout à fait claire pour moi.
Je vais essayer tes syntaxes et très probablement les inclures dans mon sources.

Si j'ai bien compris, la première ne devrait pas passer mon test, mais la deuxième si.

20 fois plus lente, mais 20 fois plus compatible!
cs_Warny Messages postés 473 Date d'inscription mercredi 7 août 2002 Statut Membre Dernière intervention 10 juin 2015
11 juil. 2005 à 11:25
A propos, la liaison précoce (early binding) permet d'accélerer la vitesse d'execution par 20 environ
cs_Warny Messages postés 473 Date d'inscription mercredi 7 août 2002 Statut Membre Dernière intervention 10 juin 2015
11 juil. 2005 à 11:17
CreateObject ne fait pas une liaison tardive !!!! Il permet seulement d'instancier la classe

si je fait
dim fso as scripting.filesystemobject
set fso = createobject("scripting.filesystemobject")
c'est une liaison précoce parce que j'indique le type de la classe et que le compilateur peut préparer tous les appels de fonctions

si je fait
dim fso as object
set fso = new scripting.filesystemobject
c'est une liaison tardive, parce que le programme doit vérifier le type à chaque appel d'une fonction

comme vous pouvez le voir, la liaison tardive n'est pas liée au createobject.
Si vous voulez utiliser des objets indiférenciés, utilisez au maximum des interfaces communes qu'implémentent ces objets.
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
23 juin 2005 à 14:35
Bien vu Patrice99!
cs_Patrice99 Messages postés 1221 Date d'inscription jeudi 23 août 2001 Statut Membre Dernière intervention 9 septembre 2018
21 juin 2005 à 08:36
>Autre exemple:
>shell "regsvr32 comctl32.ocx"
>Si un contrôle de ce fichier se trouve sur une form, le prog risque de planter au moins la première fois.

Pas du tout, il suffit de démarrer sur un module : main(), et de faire les vérifications et eventuellement les traitements appropriés, regarde ici :
www.vbfrance.com/code.aspx?ID=17783

>Quoiqu'il en soit, il faudrait faire attention de ne pas installer un fichier de version anterieure à celle précédement installer sur le PC, sinon de beaux logiciel tout neuf risquent de planter. (Mais faire attention, c'est plus facile à dire qu'à faire...)

Ce n'est pas si difficile, il suffit d'essayer d'instancier l'objet, et si cela fonctionne, alors il n'est pas besoin de le faire, et ainsi, cela peut fonctionner avec des dll ou ocx compatibles de facon ascendante, même avec des versions différentes.
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
20 juin 2005 à 16:35
Salut BOUV,

Effectivement, la recompilation de l'exe règle le problème. Mais dans le cas de plusieurs applications référençant la même dll, tu recompiles et redistribus tous les exe ?

Pour ce qui est des batchs, du fait que pratiquement tout le monde puisse lire le source, je trouve que ce sont de très mauvais vecteurs de virus et autres trojans.

Je n'aime pas CreateObject, je ne l'utilise que parce que référencer pose des problèmes de mise à jour.


Salut Patrice99,

Effectivement aussi, on peut utiliser un shell.

Toutefois, l'utilisation de batchs peut parfois s'avérer utile, je pense.

Exemple:
shell "regsvr32 msvbvm60.dll"
VB ayant besoin de ce dll, il peut diffcilement l'installer.

Autre exemple:
shell "regsvr32 comctl32.ocx"
Si un contrôle de ce fichier se trouve sur une form, le prog risque de planter au moins la première fois.

Quoiqu'il en soit, il faudrait faire attention de ne pas installer un fichier de version anterieure à celle précédement installer sur le PC, sinon de beaux logiciel tout neuf risquent de planter. (Mais faire attention, c'est plus facile à dire qu'à faire...)
cs_Patrice99 Messages postés 1221 Date d'inscription jeudi 23 août 2001 Statut Membre Dernière intervention 9 septembre 2018
17 juin 2005 à 09:25
La méthode avec createObject est appelée liaison tardive (à l'execution) par opposition à la liaison précoce ou anticipée (à la compilation). Pour info, tu n'as pas vraiment besoin de batch pour installer un ocx ou une dll activeX, tu peux le faire carrément depuis VB6 avec un Shell Regsvr32, voir : www.vbfrance.com/code.aspx?ID=17783
Personnellement, j'utilise systématiquement la liaison tardive pour que mes logiciels fonctionnent à coup sur partout. Mais je debogue souvent en liaison précoce, c'est plus pratique.
bouv Messages postés 1411 Date d'inscription mercredi 6 août 2003 Statut Membre Dernière intervention 3 mars 2019 1
16 juin 2005 à 16:26
1°-La méthode CreateObject est "beaucoup" plus lente.
2°-Quand on fait une mise à jour de la dll, il faut la redistribuer, alors pourquoi ne pas redistribuer l'exe dont elle dépend en même temps.
3°-Comme dis dans le projet : attention les fonctions ne sont pas completez automatiquement. Cela peut prendre un certain temps lors de la programmation pour ne pas faire d'erreur.
4°-Je déconseille fortement les BATCH (question de virus et le code qu'il contient peut être appelé avec un simple Shell).

Enfin, bref vous aurez compris que je ne suis pas fan de cette méthode.
Rejoignez-nous