У меня есть библиотека, которую я портирую на Windows / MSVC. Библиотека C ++, и использует следующий шаблон, чтобы скрыть реализацию. Я пытаюсь использовать предложенный способ экспортировать весь класс с dllexport
на объявлении класса.
#define API __declspec(dllexport)
class API Something
{
public:
static Something * instantiate();
void doSomething() = 0;
// etc
};
Затем есть частная реализация, которая реализует статический метод фабрики и все другие методы.
// SomethingImpl.h
class SomethingImpl : public Something
{
//... normal overrides
}
// SomethingImpl.cpp
Something * SomethingImpl::instantiate()
{
return new SomethingImpl();
}
void SomethingImpl::doSomething()
{
// something great
}
Однако, когда я думаю связать DLL с моим приложением, все эти символы не найдены компоновщиком (LNK2019). Я полагаю, что, поскольку они являются чисто виртуальными методами, предполагается, что они не нужны? Есть намеки?
Другие более нормальные классы связываются нормально, и когда я вижу библиотеку DLL в средстве обхода зависимостей, символы для этих классов определенно отсутствуют.
Спасибо
Ваше предположение верно в том смысле, что базовый класс (Something
) не экспортируется. Более конкретно, нет фактического кода, сгенерированного для базового класса (поскольку это чисто виртуальный класс). Следовательно, нет символов, которые можно было бы экспортировать.
На производном классе (SomethingImpl
) Однако вы должны dllexport частной реализации для потребителя DLL. Dllexport базового класса не наследуется производным классом. Но вы должны экспортировать эти символы в порядке, позволяющем потребителю фактически использовать этот код. Это не означает, что ваши детали реализации становятся «общедоступными» для потребителя.
В качестве примера представьте, что потребитель вашей dll объявляет класс с членом типа Something
, Когда этот класс вызывает Something::instantiate()
компоновщик должен знать, какой фактический адрес должен быть вызван. Следовательно, ваша реализация должна быть экспортирована.