Задержка загрузки DLL
Для простоты я поместил оба DLL_TUTORIAL.dll с заголовком MathFuncsDll.h в корневую папку C:\ .
Затем создал пустой проект, установив
Свойства конфигурации->Linker->Input->Delay Loaded Dll's
в
C:\DLL_TUTORIAL.dll;%(DelayLoadDLLs)
а также
Свойства конфигурации-> Каталоги VC++-> Включить каталоги
в
C:\;$(INCLUDEPATH)
Команды Complier:
/ Zi / nologo / W3 / WX- / O2 / Oi / Oy- / GL / D "_MBCS" / Gm- / EHsc / MT / GS / Gy / fp: точный /Zc:wchar_t /Zc:forScope /Fp"Release\clean_rough_draft.pch" /Fa"Release\" /Fo"Release\" /Fd"Release\vc100.pdb" /Gd /analysis- /errorReport: очередь
Этот проект содержит только файл с main.
main.cpp
#include <Windows.h>
#include <iostream>
#include "MathFuncsDll.h"
using namespace MathFuncs;
using namespace std;
int main()
{
std::cout<< MyMathFuncs<int>::Add(5,10)<<endl;
system("Pause");
return 0;
}
Dll была успешно скомпилирована в другом решении.
MathFuncsDll.h
namespace MathFuncs
{
template <typename Type>
class MyMathFuncs
{
public:
static __declspec(dllexport) Type Add(Type a, Type b);
static __declspec(dllexport) Type Subtract(Type a, Type b);
static __declspec(dllexport) Type Multiply(Type a, Type b);
static __declspec(dllexport) Type Divide(Type a, Type b);
};
}
Определения этих функций:
#include "MathFuncsDll.h"
#include <stdexcept>
using namespace std;
namespace MathFuncs
{
template <typename Type>
Type MyMathFuncs<Type>::Add(Type a,Type b)
{ return a+b; }
template <typename Type>
Type MyMathFuncs<Type>::Subtract(Type a,Type b)
{ return a-b; }
template <typename Type>
Type MyMathFuncs<Type>::Multiply(Type a,Type b)
{ return a*b; }
template <typename Type>
Type MyMathFuncs<Type>::Divide(Type a,Type b)
{
if(b == 0) throw new invalid_argument("Denominator cannot be zero!");
return a/b;
}
}
Запуск этой программы не удался:
1> main.obj: ошибка LNK2001: неразрешенный внешний символ "public: static int __cdecl MathFuncs::MyMathFuncs::Add(int,int)" (?Add@?$MyMathFuncs@H@MathFuncs@@SAHHH@Z) 1>C:\Users\Tomek\Documents\Visual Studio 2010\Projects\clean_rough_draft\Release\clean_rough_draft.exe: фатальная ошибка LNK1120: 1 неразрешенный внешний интерфейс
Не могли бы вы указать на мою ошибку?
1 ответ
Проблема не имеет ничего общего с задержкой загрузки DLL или нет. Я вижу две проблемы здесь:
Вы экспортируете шаблонные функции. Это не сработает, потому что экспорт шаблонов не поддерживается в компиляторе Visual C++ и, тем не менее, уже удален из стандарта. Для этого у вас есть два возможных решения:
- Переместите реализации методов в файл.h, таким образом, больше не требуется DLL, так как весь код находится в заголовочном файле;
- Создайте шаблоны с типами, которые вы будете использовать в своем клиентском приложении. Это делается путем помещения кода экземпляра с точными типами в ваш файл cpp, делая некоторые
extern template
объявления в заголовке и т. д. Вы можете найти это в Google для получения дополнительной информации, просто поищите "extern template DLL" или что-то подобное.
Вы только экспортируете методы при создании DLL, но никогда не импортируете их (или, по крайней мере, это то, что я вижу из кода). Ты используешь
__declspec(dllexport)
перед каждым методом, который говорит компилятору поместить эти методы в DLL. Если вы хотите использовать эти методы из клиентского приложения, вы должны импортировать их из DLL. Это делается путем размещения__declspec(dllimport)
перед каждым методом. Поскольку вы не можете поместить оба префикса в методы, вы должны либо создать два почти одинаковых заголовочных файла, которые просто различаются в зависимости от префикса этого метода, либо использовать некоторую подстановку макросов в зависимости от того, является ли это строительным кодом DLL или клиентским приложением. Еще раз, вы можете посмотреть это в Google, чтобы увидеть, как это делается.
Надеюсь, это поможет.