SupposonsAjouter quelque chose à un serveur C# COM et l'utiliser à partir de C++ sans recompiler
- Je travaille pour la société A et je fournir une DLL C# appelé
managed.dll
qui est COM visible. Je fournis aussi le fichier TLB appelémanaged.tlb
.- une société B utilise mon
managed.dll
dans un EXE C++ appeléunmanaged.exe
.- un client C doit obtenir le
managed.dll
de ma compagnie A et launmanaged.exe
de la société B. La raison est que la société B ne peut pas redistribuer lemanaged.dll
de la société A.
maintenant supposons que j'ajoute une méthode ou une propriété à l'une de mes classes dans mon managed.dll
. Ensuite, le unmanaged.exe
de la société B est cassé. La société B doit le recompiler avec le nouveau fichier tlb.
Comment puis-je éviter que la société B recompile leur unmanaged.exe
lorsque j'ajoute quelque chose à mon managed.dll
?
La raison pour laquelle je demande est
- Je n'ai pas de contrôle lorsque la société B est recompiler ou libérer leur
unmanaged.exe
. Même si je fournis monmanaged.dll
à la compagnie B chaque fois que j'ai ajouté quelque chose.- Je n'ai aucun contrôle sur les versions
managed.dll
etunmanaged.exe
que le client C utilise.- société B voudrais prétendre que leur
unmanaged.exe
V1.0 fonctionne avec monmanaged.dll
V1.0 ou plus récent.
Comment pouvons-nous y parvenir?
Le code source de mon managed.dll
ressemble à ça:
[Guid("852e5991-ddcc-56dd-8e13-90dcaf11ebe5")]
[ComVisible(true)]
public interface ITestA
{
string DummyString();
int DummyInt();
}
[Guid("41916928-6bea-43de-bedb-318df340e7b8")]
[ComVisible(true)]
[ComDefaultInterface(typeof(ITestA))]
public class TestA : ITestA
{
public string DummyString() { return "Dummy"; }
public int DummyInt() { return 123; }
}
Le fichier TLB-est généré avec RegAsm.exe managed.dll /tlb /codebase
.
Le code source du unmanaged.exe
ressemble que:
#include "stdafx.h"
#import "managed.tlb"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr = CoInitialize(NULL); // Init COM
IClassAPtr pClassA(__uuidof(ClassA));
// and so on ...
}
Cordialement Wollmich
La modification de la disposition binaire (signatures, méthodes d'ajout/de suppression, etc.) d'une interface IUnknown publiée est quelque peu interdite. Vous devez fournir de nouvelles interfaces (comme ITestA2, ITestA3, etc.). Ou vous pouvez proposer une interface Automation (late binding/IDispatch) au lieu de s'appuyer sur des dérivées IUnknown. Mais c'est en quelque sorte plus de travail du côté C++. –
@Simon Mourier: Est-ce décrit quelque part dans MSDN? Ou avez-vous une référence qui dit que je dois fournir une nouvelle interface (ITestA2) si je veux ajouter de nouvelles méthodes? – Wollmich
@Wollmich: C'est l'un de ces "Il est tellement évident que nous n'avons pas besoin de l'énoncer". Chaque interface possède un identifiant unique global (GUID). Évidemment, cela n'a de sens que si le GUID identifie quelque chose d'unique. Puisque vous définissez deux interfaces (anciennes et nouvelles), il vaut mieux avoir deux ID. – MSalters