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 !!!
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é.
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.
Le mettre à jour et expliquer comment fonctionne la compilation de dll, éventuellement, expliquer comment upgrader une dll ou comment faire une boite à outil extensible.
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).
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.
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é !
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.
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é !
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.
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 !).
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.
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é.
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.
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.
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.
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.
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.
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.
>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.
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...)
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.
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.
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 !!!
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é.