3

I tried to make a DLL that contains:

base template class, only with a virtual destructor and no attributes (I called it MatrixInterface)

a derived class with constructors, destructor, operator= and attributes (matrix class)

a function that returns a base class pointer to a new derived object:

#ifdef BUILD_DLL
    #define DLL_EXPORT __declspec(dllexport)
#else
    #define DLL_EXPORT __declspec(dllimport)
#endif

template<class T>
MatrixInterface<T> DLL_EXPORT * CreateMatrixInstance(unsigned int n,unsigned int m)
{
    return new matrix<T>(n,m);
}

I wanted to instatiate the matrix class in my program using this function, but I cannot assign a function pointer to this function and I don't understand why. I can load any function that is not a template function this way.

#include <windows.h>
#include <iostream>
using namespace std;

template<class T>
class MatrixInterface
{
public:
    virtual ~MatrixInterface(void);
};


typedef MatrixInterface<int>* (*Fptr)(unsigned int,unsigned int);

int main(int argc, char* argv[])
{
    Fptr p;
    MatrixInterface<int> *x;
    char path[]="basicmatrix.dll";
    HINSTANCE hDll = LoadLibrary(path);
    cout<<(char*)path<<endl;
    if(hDll)
    {
        cout<<"Library opened succesfully!"<<endl;
        p = (Fptr)GetProcAddress(hDll,"CreateMatrixInstance");
        if(p) {
            cout<<"working!\n";
            x=p(7,8);
            cout<<"MatrixCreated"<<endl;
            delete x;

        } else {
            cout<<"Failed loading function CreateMatrixInstance\n";
        }
    }
    else
    {
        cout<<"Failed loading library "<<(char*)path<<endl;
    }
    system("pause");
    FreeLibrary(hDll);
    return 0;
}

the base class is present in both DLL and executable file.


For some reason, Visual Studio cannot open the DLL (compiled with MSVC or MinGW). I compiled the program with MinGW and it loads the .dll file.


Can you please tell me what is wrong with my code?

Cristi
  • 1,195
  • 6
  • 17
  • 24

1 Answers1

12

Templates are resolved at compile time only ! And they are going to be different types in two different compile units. (This is the reason why it's really dangerous to export functions with std::string as parameters).

As a consquence you should explicitely instanciate the templates to the types that you are going to use / allow to be used.

In you exportimport.h file, there should be template instanciation of all the types you are going to expose in your dll. Namely MatrixInterface<int>.

You should write:

template class MatrixInterface<int>;

so as to expose one and only one type. cf. What does `class template Example<int>;` statement mean with C++11?

see documentation reference here: https://en.cppreference.com/w/cpp/language/class_template#Class_template_instantiation

Stephane Rolland
  • 38,876
  • 35
  • 121
  • 169
  • But I can't instantiate MatrixInterface, it's an abstract class... right? – Cristi Jan 03 '13 at 12:13
  • 2
    It's at compilte time ! I mean **Template Instanciation**. – Stephane Rolland Jan 03 '13 at 12:15
  • 1
    `class template ...` -- are you sure you got it right? I won't look up valid C++ syntax now, but somehow I think it should be the other way around -- `template class ...`. – Armen Michaeli Oct 27 '18 at 20:17
  • @amn go to the Documentation link given in the answer: http://www.cplusplus.com/articles/1C75fSEw/ and go to the 3rd code example, at the lines of code 18,19 an 20: This is what Template Instantion is. You are probably mistaking with Template Definition. You should open a question regarding your "class template ..." error, including the error message. As you will see in the Documentation, this should be valid syntax. Indicate your compiler version in your question also. – Stephane Rolland Oct 27 '18 at 22:18
  • 1
    @StephaneRolland I still am very unsure what does `class template ...` instruct a compliant C++11 compiler (I assume the syntax is invalid for earlier versions of C++). I have used templates before and I know I can instantiate a template using `template class Example;`. I have followed your recommendation and asked corresponding question at https://stackoverflow.com/questions/53030882/what-does-class-template-exampleint-statement-mean-with-c11, you may want to follow it up and attempt to clarify. – Armen Michaeli Oct 28 '18 at 14:00
  • 1
    @amn Many thanks for asking a dedicated question. At the time I wrote this answer I think I was still often using my Microsoft Visual C++ 10 compiler. I tend to think it was valid syntax for this compiler. I follow your question, and will update my answer according to what the standard should be for the syntax. Thanks. – Stephane Rolland Oct 28 '18 at 14:10
  • The documentation at https://en.cppreference.com/w/cpp/language/class_template#Class_template_instantiation is saying things your way: `template class...`. I will edit the answer accordingly. – Stephane Rolland Oct 28 '18 at 14:15
  • @amn Answer edited taking your correction into account. – Stephane Rolland Oct 28 '18 at 18:31
  • 1
    @StephaneRolland I appreciate your dedication to this, thank you very much for helping me and whoever stumbles upon this issue. – Armen Michaeli Oct 28 '18 at 19:31