Я попытался создать DLL, содержащую:
базовый класс шаблона , только с виртуальным деструктором и без атрибутов ( я назвал его MatrixInterface )
производный класс с конструкторами, деструктором, operator = и атрибутами ( матричный класс )
Функция, которая возвращает указатель базового класса на новый производный объект:
#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);
}
Я хотел инсталлировать матричный класс в моей программе с помощью этой функции, но я не могу присвоить этой функции указатель на функцию, и я не понимаю, почему. Таким образом я могу загрузить любую функцию, не являющуюся функцией шаблона.
#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;
}
Базовый класс присутствует как в DLL, так и в исполняемом файле.
По какой-то причине Visual Studio не может открыть DLL (скомпилированную с помощью MSVC или MinGW). Я скомпилировал программу с помощью MinGW, и она загружает файл .dll.
Подскажите, пожалуйста, что не так с моим кодом?
1 ответ
Шаблоны разрешаются только во время компиляции! И они будут разных типов в двух разных единицах компиляции. (Это причина того, почему действительно опасно экспортировать функции с параметрами std::string
).
Как следствие, вы должны явно привязать шаблоны к типам, которые вы собираетесь использовать / разрешать использовать.
В вашем файле exportimport.h
должны быть экземпляры шаблонов всех типов, которые вы собираетесь предоставить в своей dll. А именно MatrixInterface<int>
.
Вы должны написать:
template class MatrixInterface<int>;
Так, чтобы выставить один-единственный тип. ср. Что означает `шаблон шаблона класса Пример
См. ссылку на документацию здесь: https://en.cppreference.com/w/cpp / language / class_template # Class_template_instantiation
class template ...
- вы уверены, что поняли? Я не буду сейчас искать допустимый синтаксис C ++, но почему-то думаю, что должно быть наоборот - template class ...
.
class template ...
совместимому компилятору C ++ 11 (я предполагаю, что синтаксис недействителен для более ранних версий C ++). Я использовал шаблоны раньше и знаю, что могу создать экземпляр шаблона с помощью template class Example<int>;
. Я последовал вашей рекомендации и задал соответствующий вопрос на stackoverflow.com/questions/53030882/…, вы можете проследить его и попытаться уточнить.
Похожие вопросы
Связанные вопросы
Новые вопросы
c++
C++ — это язык программирования общего назначения. Изначально он разрабатывался как расширение C и имел аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде, который будет скомпилирован с помощью компилятора C++. Используйте тег версии для вопросов, связанных с конкретной стандартной версией [C++11], [C++14], [C++17], [C++20] или [C++23]. и т.д.