本文介绍了在DLL中无法导出外部的Template类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个导出模板类的类库dll。我有同一个课程的本地版本,它必须是巧合,但可以正常工作。我知道这并不意味着什么,显然有什么问题。

I am trying to create a class library dll that exports a template class. I have a local version of the same class and it must be coincidental, but it works correctly. I know this doesn't really mean much, clearly something is wrong.

库dll中导出的模板类为:

The exported template class in the library dll is:

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派生的,如下所示:

and the FooBlock class is derived from CcmBlock as follows:

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

    void process();
};

库会编译并生成dll。当我尝试构建应用程序时,得到以下消息:

The library compiles and builds the dll. When I attempt to build the application I get messages:

mainwindow.obj:-1:错误:LNK2019:未解析的外部符号 __declspec(dllimport)公共:__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: __cdecl CcmFilter::CcmFilter(void)" (__imp_??0?$CcmFilter@VFooBlock@@@@QEAA@XZ) referenced in function "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(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@@@@QEAAXPEAVCcmFrame@@@Z) referenced in function "public: __cdecl MainWindow::MainWindow(class QWidget *)" (??0MainWindow@@QEAA@PEAVQWidget@@@Z)

推荐答案

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

DLL-s are loaded at runtime, while templates are instantiated at compile time.

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

A work-around which is not ideal but might work for a very limited use case is to explicitly instantiate a template somewhere after their declaration. That is, add something like:

template class CcmFilter<FooBlock>;

有关详细信息,请参见

For details, see https://msdn.microsoft.com/en-us/library/by56e477(VS.80).aspx

这篇关于在DLL中无法导出外部的Template类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-19 10:33