views:

133

answers:

3

I have two DLLs a.dll and b.dll and in each one I have one class AClass and BClass.
I would like to have both AClass and BClass inherit and implement the same interface AbsBase which is a pure abstract class.
In each class I set up the #defines for __declspec(dllimport) and __declspect(dllexport). When I'm trying to compile I get this:

warning C4275: non dll-interface class 'AClass' used as base for dll-interface class 'AbsBase'

which basically wants me to declare AbsBase as __declspec(dllexport)
But if the compiler would have it his way, I would have to declare AbsBase to be exported from both a.dll and b.dll.

Why does the interface of a class needs to be exported?
Is there any way around it? should I really export AbsBase from both DLLs? isn't there something inherently wrong with this? (I would need to define a new XXX_EXPORT macro..)

A: 

I have a tip:

class Base {
  public:
    virtual void f() = 0;
    virtual void g() = 0;
    virtual ~Base();
};

class A: public Base {
  public:
    virtual void f();
    virtual void g();
};

class B: public Base {
  public:
    virtual void g(); // REVERSE ORDER
    virtual void f();
};

The order of f and g in virtual method table is specified in the base class and this information is very needed.

Notinlist
Yes, it is. That's why it is in the header file.
Hans Passant
+3  A: 

It looks like its a compiler warning and not an error, so it should still work. The compiler is just letting you know that you are doing something that makes it easy for you to screw up. It should be perfectly acceptable to do this as long as both DLLs and the core program agree on the definition of the base class.

You should be able to use a pragma to supress the warning:

http://forums.devx.com/archive/index.php/t-84785.html

bdk
The response from "ralph" in that thread is illuminating. @OP: You won't experience that problem ralph mentions provided that your base class remains pure abstract *forever*.
j_random_hacker
Making the base class completely pure virtual solved the problem.
shoosh
+1  A: 

This is something to fret about. The compiler has detected that code in the base class may run. It won't be pure a virtual method, it knows how to filter those. Maybe a constructor or a destructor? The failure mode is that the memory layout of the class object might not be the same in the client code vs the DLL. The runtime mayhem this causes is very hard to diagnose.

You'll be okay if as long as you can guarantee that both the client and the DLL are compiled with the exact same compile and link settings, using the exact same versions of the CRT and those tools. You can make the base class guaranteed abstract by using the non-standard __interface keyword instead of class.

Hans Passant