Je pense qu'il s'agit d'une explication correcte de ce qui se passe, et de quelques solutions de contournement potentielles.
J'ai créé un cas de test qui reproduit le problème dans la description et j'ai ensuite vidé l'IDL en utilisant OLEView à partir de l'ancienne et de la nouvelle DLL qui contenait l'interface.
Voici une comparaison de l'ancienne (à gauche) et de la nouvelle IDL de INewReport :
Des différences importantes :
-
L'UUID de interface _INewReport
a modifié
-
Un typedef appelé INewReport___v0
a été ajouté, qui fait référence à la original UUID de l'interface
(Je suppose que c'est également ce qui se passe pour le code mentionné dans la question).
Ainsi, dans le projet client, la DLL bincomp fait référence à l'UUID de l'interface originale, mais cet UUID ne correspond qu'à un nom différent ( INewReport___v0
au lieu de INewReport
) qu'à l'origine. Je pense que c'est la raison pour laquelle VB6 pense qu'il y a une incompatibilité de bincomp.
Comment résoudre ce problème ? Je n'ai pas pu faire quoi que ce soit en VB6 qui vous permette d'utiliser la DLL d'interface mise à jour avec le code client sans avoir à casser la bincomp du code client.
Une (mauvaise) option pourrait être de simplement changer la DLL du client pour utiliser la compatibilité du projet... mais cela peut ou non être acceptable dans votre cas. Cela pourrait causer la rupture de tout ce qui utilise la DLL du client, à moins que tous les consommateurs soient également recompilés. (Et cela pourrait potentiellement causer une cascade de bincomp cassés).
Une option meilleure mais plus complexe serait de définir l'interface dans IDL lui-même, d'utiliser le compilateur MIDL pour générer un typelib (fichier TLB) et de le référencer directement. Vous auriez alors un contrôle total sur le nommage de l'interface, etc. Vous pourriez utiliser l'IDL généré par OLEView comme point de départ pour réaliser cette opération.
Cette deuxième option suppose que la classe d'interface n'est réellement qu'une interface et qu'elle ne contient aucun code fonctionnel.
Voici comment j'ai configuré un cas pour reproduire ce problème :
Étape 1. Définition de l'interface originale - classe appelée INewReport
défini comme compatible binaire :
Sub ProcA()
End Sub
Sub ProcB()
End Sub
Étape 2. Créez une DLL de client de test qui met en œuvre les éléments suivants INewReport
qui est également compatible avec le système binaire :
Implements INewReport
Sub INewReport_ProcA()
End Sub
Sub INewReport_ProcB()
End Sub
Étape 3 : Ajouter ProcC
a INewReport
et recompiler (ce qui enregistre également la DLL nouvellement construite) :
(code ci-dessus, plus :)
Sub ProcC()
End Sub
Étape 4 : Essayez d'exécuter ou de compiler la DLL du client de test - vous obtenez instantanément l'erreur du PO. Il n'est pas nécessaire de modifier les références ou quoi que ce soit d'autre.