Задержка загрузки 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 или нет. Я вижу две проблемы здесь:

  1. Вы экспортируете шаблонные функции. Это не сработает, потому что экспорт шаблонов не поддерживается в компиляторе Visual C++ и, тем не менее, уже удален из стандарта. Для этого у вас есть два возможных решения:

    • Переместите реализации методов в файл.h, таким образом, больше не требуется DLL, так как весь код находится в заголовочном файле;
    • Создайте шаблоны с типами, которые вы будете использовать в своем клиентском приложении. Это делается путем помещения кода экземпляра с точными типами в ваш файл cpp, делая некоторые extern template объявления в заголовке и т. д. Вы можете найти это в Google для получения дополнительной информации, просто поищите "extern template DLL" или что-то подобное.
  2. Вы только экспортируете методы при создании DLL, но никогда не импортируете их (или, по крайней мере, это то, что я вижу из кода). Ты используешь __declspec(dllexport) перед каждым методом, который говорит компилятору поместить эти методы в DLL. Если вы хотите использовать эти методы из клиентского приложения, вы должны импортировать их из DLL. Это делается путем размещения __declspec(dllimport) перед каждым методом. Поскольку вы не можете поместить оба префикса в методы, вы должны либо создать два почти одинаковых заголовочных файла, которые просто различаются в зависимости от префикса этого метода, либо использовать некоторую подстановку макросов в зависимости от того, является ли это строительным кодом DLL или клиентским приложением. Еще раз, вы можете посмотреть это в Google, чтобы увидеть, как это делается.

Надеюсь, это поможет.

Другие вопросы по тегам