在dll unresolved external中导出Template类

时间:2016-11-27 18:29:32

标签: c++ templates 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(class QWidget *)”中引用(?? 0MainWindow @@ QEAA @ PEAVQWidget @@@ Z)

mainwindow.obj:-1:错误:LNK2019:未解析的外部符号“__declspec(dllimport)public:void __cdecl CcmFilter :: add(class CcmFrame *)”(__ imp_?add @?$ CcmFilter @ VFooBlock @@@@ QEAAXPEAVCcmFrame @@@ Z)在函数“public:__ cdecl MainWindow :: MainWindow(class QWidget *)”中引用(?? 0MainWindow @@ QEAA @ PEAVQWidget @@@ Z)

2 个答案:

答案 0 :(得分:2)

DLL-s在运行时加载,而模板在编译时实例化。

一个不理想但可能适用于非常有限的用例的解决方法是在声明后的某个地方显式实例化模板。也就是说,添加如下内容:

 ProgressBar progressBar = (ProgressBar)findViewById(R.id.happiness_progress);

有关详细信息,请参阅https://msdn.microsoft.com/en-us/library/by56e477(VS.80).aspx

答案 1 :(得分:0)

请勿使用declspec。但在您的情况下,每次将其包含在* .cpp文件中时,都会编译模板。它不会被出口。

为了导出模板的一些众所周知的实现,您可能应该使用模板显式实例化定义 __ declspec(export)一起使用。