延迟加载DLL
Delay load DLL
为了简单起见,我将标题为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的延迟加载无关。我可以在这里看到两个问题:
-
您正在导出模板化函数。这样做是行不通的,因为Visual C++编译器不支持模板导出,而且已经从标准中删除了模板导出。为此,您有两种可能的解决方案:
- 将方法的实现移动到.h文件中,因此不再需要DLL,因为所有代码都在头文件中
- 使用将在客户端应用程序中使用的类型实例化模板。这是通过在你的cpp文件中放入具有确切类型的实例化代码,在头中做一些
extern template
声明等来完成的。你可以在谷歌上查找更多信息,只需搜索"extern template DLL"或类似的东西
-
您只在创建DLL时导出方法,但从不导入它们(或者至少我从代码中看到了这一点)。在每个方法前面使用
__declspec(dllexport)
,这告诉编译器将这些方法放入DLL中。当你想从客户端应用程序中使用这些方法时,你必须从DLL中导入它们。这是通过将__declspec(dllimport)
放置在每个方法前面来完成的。由于不能在方法上同时放置两个前缀,因此必须创建两个几乎相同的头文件,只是在方法前缀方面有所不同,或者根据这是DLL构建代码还是客户端应用程序使用一些宏替换。再一次,你可以在谷歌上查找它是如何做到的。
我希望这能有所帮助。
- 为什么有些延迟加载 DLL 会立即使用 FFMPEG 卸载?
- 指向临时对象的自定义迭代器(延迟加载)
- 延迟加载加密++密码.dll
- 通过重新加载DLL,避免使用DLL预加载漏洞,任何更好的方法
- C++插件不能延迟加载dll时
- 延迟加载的 DLL 在内存中彼此相距太远
- 延迟加载opengl32.dll失败,出现Qt5
- 使用延迟加载加载正确的库 - 返回值类型错误
- 延迟加载可以被视为RAII的一个例子吗
- 是否有从另一个DLL中加载DLL的最佳实践
- 延迟加载DLL
- 延迟加载DLL时的函数原型
- MFC扩展dll资源加载问题
- DLL 无法加载:0x8007007E找不到模块。不确定导致此依赖项问题的原因
- Xcode 将 dylib 复制到具有延迟加载功能的捆绑包中
- 设计延迟加载
- 窗口C++DLL动态加载
- 使用 Boost.Python 从 DLL 动态加载 python 模块
- 在窗口中延迟加载
- 延迟加载的 DLL - 我缺少什么