2017-05-15 1 views
1
recompiling

dieetwas zu einem C# COM-Server hinzufügen und von C++ verwenden, ohne

Nehmen sie an,
  • Ich bin für das Unternehmen A zu arbeiten und ich biete eine C# DLL managed.dll genannt, die COM sichtbar ist. Ich stelle auch die TLB-Datei managed.tlb zur Verfügung.
  • ein Unternehmen B verwendet meine managed.dll in einer C++ EXE namens unmanaged.exe.
  • ein Kunde C hat die managed.dll von meiner Firma A und die unmanaged.exe von Unternehmen B. Der Grund dafür ist, dass Unternehmen B die managed.dll von Firma A zu verteilen bekommen erlaubt
nicht

Jetzt Nehmen wir an, ich füge eine Methode oder Eigenschaft zu einer meiner Klassen in meinem managed.dll hinzu. Dann ist die unmanaged.exe von Firma B defekt. Unternehmen B muss es mit der neueren TLB-Datei neu kompilieren.

Wie kann ich vermeiden, dass Firma B ihre unmanaged.exe neu kompilieren muss, wenn ich etwas zu meinem managed.dll hinzufügen?

Der Grund, warum ich frage ist

  • ich keine Kontrolle haben, wenn das Unternehmen B ist ihre unmanaged.exe neu zu kompilieren oder freigibt. Auch wenn ich meine Firma managed.dll jedes Mal beistelle, wenn ich etwas hinzugefügt habe.
  • Ich habe keine Kontrolle, welche Versionen der managed.dll und unmanaged.exe der Kunde C verwendet.
  • Firma B möchte behaupten, dass ihre unmanaged.exe V1.0 arbeitet mit meinem managed.dll V1.0 oder neuer.

Wie können wir das erreichen?

Der Quellcode meiner managed.dll sieht wie folgt aus:

[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; } 
} 

der TLB-Datei wird mit RegAsm.exe managed.dll /tlb /codebase erzeugt.

Der Quellcode des unmanaged.exe sieht wie folgt aus:

#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 ... 
} 

Grüße Wollmich

+2

Das Ändern des binären Layouts (Signaturen, Hinzufügen/Entfernen von Methoden usw.) einer veröffentlichten IUnknown-Schnittstelle ist irgendwie verboten. Sie müssen neue Schnittstellen bereitstellen (wie ITestA2, ITestA3 usw.). Oder Sie könnten eine Automation-Schnittstelle (späte Bindung/IDispatch) vorschlagen, anstatt auf IUnknown-Derivate zu vertrauen. Aber es ist irgendwie mehr Arbeit auf der C++ Seite. –

+0

@Simon Mourier: Wird dies irgendwo in MSDN beschrieben? Oder haben Sie eine Referenz, die besagt, dass ich eine neue Schnittstelle (ITestA2) bereitstellen muss, wenn ich neue Methoden hinzufügen möchte? – Wollmich

+0

@Wollmich: Es ist einer von denen "Es ist so offensichtlich, dass wir es nicht sagen müssen" Dinge. Jede Schnittstelle hat eine global eindeutige ID (GUID). Offensichtlich macht das nur Sinn, wenn die GUID etwas identifiziert, das tatsächlich einzigartig ist. Da Sie zwei Schnittstellen (alt und neu) definieren, haben Sie besser zwei IDs. – MSalters

Antwort

0

Es stellte sich heraus, dass ich neue Schnittstellen (wie ITestA2, ITestA3, etc.) bereitstellen muss, wenn ich neue Methoden oder Eigenschaften zu meinem managed.dll hinzufügen möchte.

für .NET

In COM-Schnittstellen können voneinander erben

[Guid("5ff6c41a-6e4c-4d96-8e5e-72a560715b56")] 
[ComVisible(true)] 
public interface ITestA2 
{ 
    string DummyString(); 
    int DummyInt(); 
    bool DummyBool(); // new method 
} 

[Guid("d5b8f4b5-d33f-4e7d-866c-ef0844216a3a")] 
[ComVisible(true)] 
[ComDefaultInterface(typeof(ITestA2))] 
public class TestA2 : TestA, ITestA2 
{ 
    public bool DummyBool() { return true; } 
} 

Bemerkungen:

So ist der Quellcode des managed.dll so könnte verlängert. Die .NET-Implementierung, die die .NET-Schnittstelle für COM verfügbar macht, unterstützt jedoch keine Vererbung. Daher müssen Sie alle Schnittstellenelemente in einer Basisschnittstelle zur abgeleiteten Schnittstelle replizieren.

siehe COM Interop: Base class properties not exposed to COM.

1

Es gibt einen Grund Microsoft IHTMLEventObj6 definiert. Das ist das fünfte inkrementelle Update von IHTMLEventObj. Sie müssen dasselbe tun: ITestA2 muss ITestA erben und zusätzliche Methoden hinzufügen.

Verwandte Themen