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?
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. NamelyMatrixInterface<int>
.You should write:
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