Library project and template class gives unresolved external



  • I have a library project im building in windows that exports a number of classes which all work. I just added a template class and when I attempt to instantiate it I get the following message:

    unresolved external symbol "__declspec(dllimport) public: __cdecl Filter<class FooBlock>::Filter<class FooBlock>(void)"
    

    The class header file is:

    template <class Block>
    class CCMSHARED_EXPORT Filter
    {
    public:
        Filter();
        void add(Frame* frame);
        Block* get();
        virtual void process();
    private:
        Block* mBlock;
    };
    

    the implementation class is

    template <class Block>
    Filter<Block>::Filter()
    {
    }
    
    template <class Block>
    void Filter<Block>::add(Frame* frame)
    {
        mBlock = new Block(
                    frame->getData(),
                    frame->getRate(),
                    0xFFFFFFFF,
                    frame->getSize(),
                    frame->getDomain()
                    );
    }
    
    template <class Block>
    Block* Filter<Block>::get()
    {
        return mBlock;
    }
    
    template <class Block>
    void Filter<Block>::process()
    {}
    

    and Foo block is a class that is derived from Block as

    class FooBlock : public Block
    {
    public:
        FooBlock(int* ipData, DWORD dwRate, DWORD dwIndex, DWORD dwSize, Domain domain);
        void process();
    };
    

  • Lifetime Qt Champion

    Hi,

    You also need to export Block and FooBlock.



  • I do export Block. FooBlock is in the application project that uses the library. I have never used templates before and I think this is where the problem is. I built a version where everything is in the application project and get the same message. Maybe because I explicitly named the template class the compiler can't use a derived class. I even made a function pure virtual and the message is the same.



  • I figured out the issue with the unresolved external symbol. The template needs to be contained all in a single header file, there can be no .cpp files for the implementation. I of course have to understand this better.

    I now get the error:

    CcmFilter.h:26: error: C2491: 'CcmFilter<CcmBlock>::CcmFilter' : definition of dllimport function not allowed
    CcmFilter.h:40: error: C2491: 'CcmFilter<CcmBlock>::add' : definition of dllimport function not allowed

    for the header file ccm_global.h, CCM_LIBRARY is defined in the .pro

    #if defined(CCM_LIBRARY)
    #  define CCMSHARED_EXPORT Q_DECL_EXPORT
    #else
    #  define CCMSHARED_EXPORT Q_DECL_IMPORT
    #endif
    

    the header file for the template

    template <class CcmBlock> class CCM SHARED_EXPORT CcmFilter
    {
    public:
        CcmFilter();
    
        void add(CcmFrame* frame);
        CcmBlock* get();
    
    private:
        CcmBlock* mBlock;
    };
    
    template <class CcmBlock> CcmFilter<CcmBlock>::CcmFilter()
    { }
    
    template <class CcmBlock> void CcmFilter<CcmBlock>::add(CcmFrame* frame)
    {
        mBlock = new CcmBlock(
                frame->getFrameData(),
                frame->getSampleRate(),
                0xFFFFFFFF,
                frame->getBlockSize(),
                frame->getDomain()
                );
    }
    
    template <class CcmBlock> CcmBlock* CcmFilter<CcmBlock>::get()
    {
        return mBlock;
    }
    

    It seems that the CCM_LIBRARY is not being used for the definitions of the member functions?


  • Lifetime Qt Champion

    Didn't thought about that one but indeed, template method implementation should be at the same place the template is declared.

    For more about templates see here.


  • Moderators

    @nefarious Remove SHARED_EXPORT as it is not needed.


  • Lifetime Qt Champion

    Just a precision, @jsulm means that for the template class.


  • Moderators

    @SGaist Yes :-)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.