2016-11-27 9 views
1

テンプレートクラスをエクスポートするクラスライブラリ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 @)関数で参照 "公共:__cdeclメインウィンドウ::メインウィンドウ(クラスはQWidget *)"(?? 0MainWindow @@ QEAA @ PEAVQWidget @@@ Z)

メインウィンドウ。外部のシンボル "__declspec(dllimport)public:void __cdecl CcmFilter :: add(クラスCcmFrame *)"(__imp_?add @?$ CcmFilter @ VFooBlock @@@@ QEAAXPEAVCcmFrame @@@ Z:エラー:LNK2019:未解決の外部シンボル)関数 "public:__cdecl MainWindow :: MainWindow(クラスQWidget *)"で参照されています(0MainWindow @@ QEAA @ PEAVQWidget @@@ Z)

+1

テンプレートは、DLLの一部にすることはできません参照してください。それは、のようなものを追加しています。 DLLの一部であるテンプレートのインスタンス化を行うことができます。 –

+0

@Vaughnはdllのstd :: listではありませんか? – Nefarious

+0

いいえ、ヘッダーにあります。 –

答えて

0

declspecを使用しないでください。しかし、あなたのケーステンプレートは、* .cppファイルに含めるたびにコンパイルされます。それは輸出されません。ために

あなたはおそらく__declspec(エクスポート)と並行してテンプレート明示的なインスタンスの定義を使用する必要があり、あなたのテンプレートのいくつかのよく知られている実装をエクスポートします。

+0

ありがとう、私は頭にF#rtを持っていたと思う、私はそれがヘッダーにあることを知っている、私はそれを私のアプリケーションクラスに含め、本当のクラスとして。 – Nefarious

0

DLLは実行時にロードされ、テンプレートはコンパイル時にインスタンス化されます。

非常に限定されたユースケースではうまくいかないかもしれない回避策は、宣言の後にテンプレートを明示的にインスタンス化することです。詳細については、

template class CcmFilter<FooBlock>; 

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

関連する問題