【问题标题】:Delay load DLL延迟加载DLL
【发布时间】:2012-08-22 00:34:37
【问题描述】:

为简单起见,我将 DLL_TUTORIAL.dll 和标头 MathFuncsDll.h 都放在了根文件夹 C:\ 中。

然后,创建空项目,设置

Configuration Properties->Linker->Input->Delay Loaded Dll's

C:\DLL_TUTORIAL.dll;%(DelayLoadDLLs)

配置属性->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"发布\clean_rough_draft.pch" /Fa"发布\" /Fo"发布\" /Fd"Release\vc100.pdb" /Gd /analyze- /errorReport:queue

此项目仅包含带有 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 unresolved externals

你能指出我的错误吗?

【问题讨论】:

  • 不支持导出模板方法。您必须将它们放在 .h 文件中。这会留下一个空的 DLL。
  • 详细地说,模板方法不是“真正的”方法——它们只是用于在编译时创建方法的模具。因此模板方法不会编译成目标代码。

标签: c++ visual-studio-2010 templates dll


【解决方案1】:

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

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

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

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 2010-11-26
    • 2017-02-11
    • 1970-01-01
    • 2021-05-06
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    相关资源
    最近更新 更多