Экспорт родительского класса без базового класса в C ++ - PullRequest
3 голосов
/ 29 ноября 2011

Учитывая классы Foo и Bar, где Bar получено из Foo, как я могу экспортировать Bar без необходимости экспортировать Foo?

Foo.h

class Foo
{
    public:
        Foo();
        virtual bool Read(...);
        virtual bool Write(...);
        ~Foo();
};

Бар.ч

#ifdef BUILD_DLL
#    include "Foo.h"
#    define EXTERNAL __declspec(dllexport)
#else
#    define EXTERNAL __declspec(dllimport)
#endif 

class EXTERNAL Bar: public Foo
{
    public:
        Bar();
        bool Read(...);
        bool Write(...);
        ~Bar();
};

Редактировать

Это предупреждение, которое Visual C ++ 2010 дает мне:

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

Edit # 2

Вот что я сделал, чтобы решить проблему.Я сделал Foo и Bar отдельные библиотеки DLL.Клиентское приложение ссылается на Bar.dll, а Bar.dll - на Foo.dll.Это хорошо работает для того, чего я пытался достичь ...

Ответы [ 4 ]

3 голосов
/ 29 ноября 2011

Разве это не работает? Должно. То, что вы не экспортируете класс явно, не означает, что логика не в двоичном коде. Символы просто не видны никому, импортирующему этот класс.

Ваше решение должно это сделать. Вы получаете ошибки связывания или что?

РЕДАКТИРОВАТЬ: я только что видел, как вы включили заголовок для Foo только в одном случае. Вам не нужно этого делать:

#ifdef BUILD_DLL
#    define EXTERNAL __declspec(dllexport)
#else
#    define EXTERNAL __declspec(dllimport)
#endif 

#include "Foo.h"

class EXTERNAL Bar: public Foo
{
    public:
        Bar();
        bool Read(...);
        bool Write(...);
        ~Bar();
};

Таким образом, вы не можете использовать Foo в другом модуле, так как он не экспортируется, но вы можете использовать и объявить Bar.

1 голос
/ 29 ноября 2011

Я не уверен, для чего это хорошо?

Если вы просто пытаетесь скрыть Foo от своих клиентов (как я иногда это делаю, но не с Foo), просто экспортируйте его как обычно ...

Сделайте из него Dll (свяжите Foo.cpp с вашим Bar.dll) и убейте класс Foo из заголовков, которые вы поставляете вместе с файлом библиотеки / Dll.

Унаследованный класс не виден пользователю dll (если вы не хотите экспортировать методы этого класса с помощью #define EXTERNAL __declspec (dllexport).

Итак: Foo скрыт для пользователя / клиента.

Просто расслабься;)

1 голос
/ 29 ноября 2011

Foo необходим для создания экземпляра Bar - фактически, для создания Bar конструктор Foo вызывается до конструктора Bar.

Я очень сомневаюсь, что вы можете экспортировать один и использовать его без экспорта другого.

0 голосов
/ 29 ноября 2011

Как уже упоминалось ранее, вы не можете сделать это так, как вы предлагаете.

Не могли бы вы предоставить описание вашего варианта использования? Может быть, некоторые другие решения будут полезны? F.ex. если вам нужно передать объект Bar за пределы dll, вы можете создать интерфейс к нему и открыть его вместо объекта Bar.

...