Wollmich
Wollmich

Reputation: 1646

Add something to a C# COM server and use it from C++ without recompiling

Let's assume

  • I'm working for company A and I provide a C# DLL called managed.dll which is COM visible. I provide as well the TLB file called managed.tlb.
  • a company B is using my managed.dll in a C++ EXE called unmanaged.exe.
  • a customer C has to get the managed.dll from my company A and the unmanaged.exe from company B. The reason for that is that company B is not allowed to redistribute the managed.dll from company A.

Now let's assume I add a method or property to one of my classes in my managed.dll. Then the unmanaged.exe from company B is broken. Company B has to recompile it with the newer tlb-file.

How can I avoid that company B has to recompile their unmanaged.exe when I add something to my managed.dll?

The reason why I'm asking is

  • I've no control when company B is recompiling or releasing their unmanaged.exe. Even if I provide my managed.dll to company B every time I've added something.
  • I've no control which versions of the managed.dll and unmanaged.exe the customer C is using.
  • company B would like to claim that their unmanaged.exe V1.0 is working with my managed.dll V1.0 or newer.

How can we achieve that?

The source code of my managed.dll looks like that:

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

The tlb-file is generated with RegAsm.exe managed.dll /tlb /codebase.

The source code of the unmanaged.exe looks like that:

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

Regards Wollmich

Upvotes: 1

Views: 94

Answers (2)

Wollmich
Wollmich

Reputation: 1646

It turned out that I've to provide new interfaces (like ITestA2, ITestA3, etc.) if I want to add new methods or properties to my managed.dll.

So the source code of the managed.dll could be extended like that:

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

Remarks for .NET

In COM interfaces can inherit from one another. However the .NET implementation that exposes the .NET interface to COM does not support inheritance. Therefore you must replicate any interface members in a base interface to the derived interface.

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

Upvotes: 0

MSalters
MSalters

Reputation: 180145

There's a reason Microsoft defined IHTMLEventObj6. That's the 5th incremental update of IHTMLEventObj. You'll need to do the same: ITestA2 will need to inherit ITestA and add extra methods.

Upvotes: 2

Related Questions