none
C++: .EXE with .DLL (LNK2019 error with template class) RRS feed

  • Вопрос

  • Environment: VS2013
    OS: Win7

    I've got a two projects - the first is a dll-project, and the second is an exe-project. I'm need to use some template class from .dll in my main .exe project.

    ==== ==== ==== ==== ==== ==== ==== ====

    DLL-Project:

    - MyClass.h -

    template <class T> class A
    {
    public:
    	DWORD Test(DWORD dw);
    };

    ----

    - MyClass.cpp -

    #include "MyClass.h"
    
    template <class T> DWORD A<T>::Test(DWORD dw)
    {
    	return dw * 5;
    }

    ==== ==== ==== ==== ==== ==== ==== ====

    EXE-Project:

    - Main.cpp -

    #include "MyClass.h"
    #pragma comment(lib, "DLL_MyClass")
    
    class HelpClass { };
    
    void Main()
    {
    	A<HelpClass> * ahc;
    	ahc->Test(5); // Here i have an error LNK2019
    }

    ==== ==== ==== ==== ==== ==== ==== ====

    12 июля 2014 г. 19:55

Ответы

  • kosuke904, спасибо за помощь! Проблему решил следующим образом:

    ==== ==== ==== ==== ==== ==== ==== ====

    DLL-Project:

    - MyClass.h -

    template <class T> class A
    {
    public:
    	DWORD Test(DWORD dw);
    };

    ----

    - MyClass.cpp -

    #include "MyClass.h"
    
    template <> DWORD A<T>::Test(DWORD dw)
    {
    	return dw * 5;
    }

    ==== ==== ==== ==== ==== ==== ==== ====

    EXE-Project:

     - Main.cpp -

    #include "MyClass.h"
    #pragma comment(lib, "DLL_MyClass")
    
    void Main()
    {
    	A<DWORD> * ahc = 0; // Формальная инициализация, чтобы не было ошибки
    	ahc->Test(5);
    }
     ==== ==== ==== ==== ==== ==== ==== ====
    14 июля 2014 г. 9:25

Все ответы

  • Во-первых, чтобы вызывать функцию из dll, она должна экспортироваться из нее. См. ключевое слово _declspec.

    Во-вторых, экспортировать реализацию шаблона для произвольного параметра невозможно в принципе. Проще всего включить реализацию методов шаблона непосредственно в заголовочный файл (.h), как это сделано в STL.


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    12 июля 2014 г. 21:28
  • Да, забыл сказать, это русскоязычный форум, пишите на родном языке :)

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    12 июля 2014 г. 21:30
  • Во-первых, чтобы вызывать функцию из dll, она должна экспортироваться из нее. См. ключевое слово _declspec.

    Я знаю о таком варианте подключения библиотеки, но у меня подключение будет производиться через .lib и .h .
    13 июля 2014 г. 9:12
  • Да, забыл сказать, это русскоязычный форум, пишите на родном языке :)
    Ночью не сообразил :)
    13 июля 2014 г. 9:14
  • Библиотека может быть либо статической, либо динамической. И в первом и во втором случае используются файлы с расширением .lib (только смысл этих файлов разный). Вы пишете о dll, т.е. о динамическом подключении. В отличии от nix-систем, где все идентификаторы экспортируются из dll автоматически, в Windows Вы обязаны четко указать, что будет экспортироваться, а что нет. Делается это указанием в объявлении идентификатора ключевого слова _declspec(dllexport) на стороне dll, и _declspec(dllimport) на стороне exe. В случае экспорта шаблона Вы обязаны реализовать методы шаблона для всех возможных параметров (шаблона) и экспортировать их. Т.к. предвосхитить все возможные типы параметра шаблона нельзя, реализацию класса шаблона размещают в заголовочном файле и он правильно компилируется на стороне exe. Никакого экспорта в данном случае не требуется.

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    13 июля 2014 г. 9:29
  • kosuke904, спасибо за помощь! Проблему решил следующим образом:

    ==== ==== ==== ==== ==== ==== ==== ====

    DLL-Project:

    - MyClass.h -

    template <class T> class A
    {
    public:
    	DWORD Test(DWORD dw);
    };

    ----

    - MyClass.cpp -

    #include "MyClass.h"
    
    template <> DWORD A<T>::Test(DWORD dw)
    {
    	return dw * 5;
    }

    ==== ==== ==== ==== ==== ==== ==== ====

    EXE-Project:

     - Main.cpp -

    #include "MyClass.h"
    #pragma comment(lib, "DLL_MyClass")
    
    void Main()
    {
    	A<DWORD> * ahc = 0; // Формальная инициализация, чтобы не было ошибки
    	ahc->Test(5);
    }
     ==== ==== ==== ==== ==== ==== ==== ====
    14 июля 2014 г. 9:25