【问题标题】:exporting Template class in dll unresolved external在 dll 中导出模板类未解析的外部
【发布时间】:2017-04-11 11:20:02
【问题描述】:

我正在尝试创建一个导出模板类的类库 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: error: LNK2019: unresolved external symbol "__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: error: LNK2019: unresolved external symbol "__declspec(dllimport) public: void __cdecl CcmFilter::add(class CcmFrame *)" (__imp_?add@?$CcmFilter@VFooBlock@@@@函数“public: __cdecl MainWindow::MainWindow(class QWidget *)”中引用的 QEAAXPEAVCcmFrame@@@Z) (??0MainWindow@@QEAA@PEAVQWidget@@@Z)

【问题讨论】:

  • 模板不能是 DLL 的一部分。您可以拥有属于 DLL 一部分的模板实例化。
  • @Vaughn 不是 dll 中的 std::list 吗?
  • 不,它在标题中。
  • @Vaughn 我数不清有多少次我读到“这是一个标题,而且确实是”,但仍然对它在 dll 中的心理障碍感到恼火。谢谢,感谢您再次向我指出这一点:)

标签: c++ templates dll


【解决方案1】:

只是不要使用declspec。但是在您的情况下,每次将模板包含在 *.cpp 文件中时都会对其进行编译。它不会被导出。

为了导出模板的一些知名实现,您可能应该将模板显式实例化定义__declspec(export)结合使用。

【讨论】:

  • 谢谢,我想我对此很有脑子 F#rt,我知道它在标题中,我将它包含在我的应用程序类中,并且仍然认为它是一个真正的类。
【解决方案2】:

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

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

template class CcmFilter<FooBlock>;

详情见https://msdn.microsoft.com/en-us/library/by56e477(VS.80).aspx

【讨论】:

  • 仅供参考,链接现在已断开。 (为什么微软在可以重定向时总是这样做......)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-31
  • 2014-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-12
相关资源
最近更新 更多