Чистый базовый класс нужно экспортировать из DLL? - PullRequest
5 голосов
/ 04 февраля 2010

У меня есть две DLL a.dll и b.dll, и в каждой из них есть один класс AClass и BClass.
Я хотел бы, чтобы и AClass, и BClass наследовали и реализовывали один и тот же интерфейс AbsBase, который является чисто абстрактным классом.
В каждом классе я настраивал #defines для __declspec (dllimport) и __declspect (dllexport). Когда я пытаюсь скомпилировать, я получаю это:

предупреждение C4275: не интерфейс класса dll 'AClass', используемый в качестве базы для класса интерфейса dll 'AbsBase'

, который в основном хочет, чтобы я объявил AbsBase как __declspec (dllexport)
Но если компилятор будет по-своему, я должен объявить, что AbsBase экспортируется как из a.dll, так и из b.dll.

Почему интерфейс класса необходимо экспортировать?
Есть ли способ обойти это? я действительно должен экспортировать AbsBase из обеих DLL? разве с этим что-то не так? (Мне нужно определить новый макрос XXX_EXPORT ..)

Ответы [ 3 ]

3 голосов
/ 04 февраля 2010

Похоже, это предупреждение компилятора, а не ошибка, поэтому все равно должно работать. Компилятор просто сообщает вам, что вы делаете что-то, что позволяет вам легко облажаться. Это должно быть вполне приемлемо, если обе библиотеки DLL и основная программа согласуются с определением базового класса.

Вы должны быть в состоянии использовать прагму для подавления предупреждения:

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

1 голос
/ 04 февраля 2010

Это то, что надо беспокоиться. Компилятор обнаружил, что код в базовом классе может выполняться. Это не будет чисто виртуальный метод, он знает, как их фильтровать. Может быть, конструктор или деструктор? Режим сбоя заключается в том, что структура памяти объекта класса может не совпадать в коде клиента и DLL. Причиной этого может быть очень трудно диагностируемый.

С вами все будет в порядке, если вы можете гарантировать, что и клиент, и DLL скомпилированы с одинаковыми настройками компиляции и компоновки, используя одинаковые версии CRT и этих инструментов. Вы можете сделать базовый класс гарантированно абстрактным, используя нестандартное ключевое слово __interface вместо класса.

0 голосов
/ 04 февраля 2010

У меня есть совет:

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();
};

Порядок f и g в таблице виртуальных методов указан в базовом классе, и эта информация очень нужна.

...