Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding a new inherited "interface" and virtual methods require recompile

Tags:

c++

interface

dll

There are existing answers that cover the general cases, but they are slightly vague and I need to be certain on this.

Consider:

  • An existing defined class that derives from an abstract base class "interface".
  • Class is a part of a library that is compiled into multiple dlls that talk to each other through the interface.

Then add:

  • A second "interface" from which the defined class would now be derived (so now it has two interfaces).
  • New virtual methods to the defined class that are accessed by the new interface.

Do I need to recompile every dll that links this library, or only the dlls that use the new methods?

EDIT:

My original interface exposes a dynamic method which is Dynamic(int OP, void* args) would it be possible to add an op that casts to the new interface?

How does COM manage to add new interfaces to objects without corrupting the existing interfaces? Does it stack interfaces, use multiple-inheritance, etc???

Let me lay out the way this works.

Statically Linked Library Interfaces

In statically linked library

class Interface1
{
    virtual Method1() = 0;
    virtual Method2() = 0;
}
class NotReallyInterface2 : Interface1
{
    virtual Method1() = 0;
    virtual Method2() { // does something }
}

In dlls

In A.dll

Load statically linked library
class A : NotReallyInterface2
{
    virtual Method1() { // does something }
}

In B.dll

Load statically linked library
class B: NotReallyInterface2
{
     virtual Method1() { // does something different }
}

I want to add

class Interface3
{
     virtual Method3() = 0;
}

I have some problem here because my inheritance structure looks like.

[a.dll [ library : Interface1 < NotReallyInterface2 ] < A ]
[b.dll [ library : Interface1 < NotReallyInterface2 ] < B ]

so I'm afraid

[ a.dll [ library : Interface1 < NotReallyInterface2 ] < Interface3 < A ]

won't work.

Edit 2

So I found my problem. Apparently, other dlls and executables are referencing my NotReallyInterface2. This means that multiple dlls and exes are building the same base class. So if those "copies" of the base class get out of sync, down goes the ship. Which means I can't change a single method signature in NotReallyInterface2.

This would have worked had no one referenced NotReallyInterface2 and I now get that out of the answers and the whole thing makes sense.

like image 345
Lee Louviere Avatar asked Mar 22 '23 20:03

Lee Louviere


1 Answers

You need to recompile those DLLs that reference the derived class directly. Those that only reference it through the interface will continue to work.

COM relies on this very thing. The COM ABI specification effectively makes it a requirement for every compatible C++ compiler not to screw with vtables in a way that makes interfaces stop working. That's why one of the fundamental requirements of COM is that you never ever modify a published interface, by adding/removing/changing functions or giving it a new base interface.

Adding a new interface by having it derive the old one and make the implementing class derive from the new interface doesn't break that; neither does multiple inheritance from many interfaces in the implementing class.

The not-so-abstract class ought not to get in the way, but now you're outside the guarantees of COM. If that class has data members, it gets even worse. I think it would still be safe not to recompile the code, but I wouldn't want to rely on it anymore.

like image 97
Sebastian Redl Avatar answered Apr 06 '23 20:04

Sebastian Redl