Экспорт класса шаблона в dll неразрешенный внешний

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

Класс экспортируемого шаблона в библиотеке dll:

template <class CcmBlock>
class CCMSHARED_EXPORT CcmFilter
{
public:
    CcmFilter()
    {
        mBlock = nullptr;
        ////mBlockList = new std::list<CcmBlock*>();
    }

    void add(CcmFrame* frame)
    {
        if (frame == nullptr)
            return;

        mBlock = new CcmBlock(
                    frame->getFrameData(),
                    frame->getSampleRate(),
                    0xFFFFFFFF,
                    frame->getBlockSize(),
                    frame->getDomain()
                    );
        mBlockList->push_back(aBlock);
    }

    CcmBlock* get()
    {
        return mBlock;
    }
private:
    CcmBlock* mBlock;
    ////std::list<CcmBlock*>* mBlockList;
};

На стороне приложения:

    CcmFilter<FooBlock>* oneFilter = new CcmFilter<FooBlock>();
    //Filter<Block>* filter = new Filter<Block>();

    CcmFrame* frame = new CcmFrame(0, 50000, 40, 1024, Domain::Time);

    oneFilter->add(frame);
    CcmBlock* block = oneFilter->get();
    FooBlock* fooBlock = dynamic_cast<FooBlock*>(block);
    if (fooBlock == nullptr)
    { //Report Error }
    else
    { // Do the work}

и класс FooBlock является производным от CcmBlock следующим образом:

class FooBlock : public CcmBlock
{
public:
    FooBlock(int* ipblock, DWORD dwSampleRate, DWORD dwMicrophoneIndex, DWORD dwBlockSize, Domain domain);

    void process();
};

Библиотека компилирует и собирает dll. Когда я пытаюсь собрать приложение, я получаю сообщения:

mainwindow.obj: -1: ошибка: LNK2019: неразрешенный внешний символ "__declspec(dllimport) public: __cdecl CcmFilter::CcmFilter(void)" (__imp_??0?$CcmFilter@VFooBlock@@@@QEAA@XZ), на который ссылается функция "public: __cdecl MainWindow::MainWindow(класс QWidget *)" (??0MainWindow@@QEAA@PEAVQWidget@@@Z)

mainwindow.obj: -1: ошибка: LNK2019: неразрешенный внешний символ "__declspec(dllimport) public: void __cdecl CcmFilter::add(класс CcmFrame *)" (__imp_?add@?$CcmFilter@VFooBlock@@@@QEAAXPEAVCcmFme @Z) упоминается в функции "public: __cdecl MainWindow::MainWindow(класс QWidget *)" (??0MainWindow@@QEAA@PEAVQWidget@@@Z)

2 ответа

DLL-ы загружаются во время выполнения, а шаблоны создаются во время компиляции.

Обходной путь, который не идеален, но может работать для очень ограниченного варианта использования, заключается в явном создании экземпляра шаблона где-то после их объявления. То есть добавить что-то вроде:

template class CcmFilter<FooBlock>;

Для получения дополнительной информации см. https://msdn.microsoft.com/en-us/library/by56e477(VS.80).aspx

Просто не пользуюсь declspec, Но в вашем случае шаблон будет компилироваться каждый раз, когда вы включаете его в файл *.cpp. Это не будет экспортироваться.

Чтобы экспортировать некоторые известные реализации вашего шаблона, вы, вероятно, должны использовать явные определения экземпляров шаблона в тандеме с __declspec (export).

Другие вопросы по тегам