延迟加载DLL

Delay load DLL

本文关键字:DLL 延迟加载      更新时间:2023-10-16

为了简单起见,我将标题为MathFuncsDll.h的DLL_UTORIAL.DLL都放在了根文件夹C:\中。

然后,创建空项目,设置

配置属性->链接器->输入->延迟加载Dll的

C: \DLL_TUTORIAL.DLL;%(DelayLoadDLL)

配置属性->VC++目录->包括目录

C: \$(IncludePath)

更复杂的命令:

/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/analyze-/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@数学函数@@SAHHH@Z)1> C:\Users\Tomek\Documents\Visual Studio 2010\Projects\clean_rough_draft\Release \clean_rough_draft.exe:致命错误LNK1120:1个未解析的外部

你能指出我的错误吗?

问题与DLL的延迟加载无关。我可以在这里看到两个问题:

  1. 您正在导出模板化函数。这样做是行不通的,因为Visual C++编译器不支持模板导出,而且已经从标准中删除了模板导出。为此,您有两种可能的解决方案:

    • 将方法的实现移动到.h文件中,因此不再需要DLL,因为所有代码都在头文件中
    • 使用将在客户端应用程序中使用的类型实例化模板。这是通过在你的cpp文件中放入具有确切类型的实例化代码,在头中做一些extern template声明等来完成的。你可以在谷歌上查找更多信息,只需搜索"extern template DLL"或类似的东西
  2. 您只在创建DLL时导出方法,但从不导入它们(或者至少我从代码中看到了这一点)。在每个方法前面使用__declspec(dllexport),这告诉编译器将这些方法放入DLL中。当你想从客户端应用程序中使用这些方法时,你必须从DLL中导入它们。这是通过将__declspec(dllimport)放置在每个方法前面来完成的。由于不能在方法上同时放置两个前缀,因此必须创建两个几乎相同的头文件,只是在方法前缀方面有所不同,或者根据这是DLL构建代码还是客户端应用程序使用一些宏替换。再一次,你可以在谷歌上查找它是如何做到的。

我希望这能有所帮助。