为简单起见,我已将DLL_TUTORIAL.dll和标题MathFuncsDll.h放在根文件夹C:\中。
然后,创建空项目,设置
配置属性 - >链接器 - >输入 - >延迟加载的Dll
到
C:\ DLL_TUTORIAL.dll;%(DelayLoadDLLs)
和
配置属性 - > VC ++目录 - >包含目录
到
C:\; $(INCLUDEPATH)
编制命令:
/ Zi / nologo / W3 / WX- / O2 / Oi / Oy- / GL / D“_MBCS”/ Gm- / EHsc / MT / GS / Gy / fp:precise / Zc:wchar_t / Zc:forScope /Fp"Release\clean_rough_draft.pch“/ Fa”Release \“/ Fo”Release“” /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&gt; main.obj:错误LNK2001:未解析的外部符号“public:static int __cdecl MathFuncs :: MyMathFuncs :: Add(int,int)”(?添加@?$ MyMathFuncs @ H @ MathFuncs @@ SAHHH @ Z ) 1&gt; C:\ Users \ Tomek \ Documents \ Visual Studio 2010 \ Projects \ clean_rough_draft \ Release \ clean_rough_draft.exe:致命错误LNK1120:1个未解析的外部
你能指出我的错误吗?
答案 0 :(得分:3)
该问题与DLL的延迟加载无关。我在这里可以看到两个问题:
您正在导出模板化函数。这不会那样,因为Visual C ++编译器不支持模板导出,但是已经从标准中删除了。为此,您有两种可能的解决方案:
extern template
声明等。您可以在Google中查找更多信息,只需搜索“extern模板DLL”或其他内容类似。您只在创建DLL时导出方法,但从不导入它们(或者至少是我从代码中看到的)。您在每个方法前面使用__declspec(dllexport)
,它告诉编译器将这些方法放在DLL中。如果要从客户端应用程序使用这些方法,则必须从DLL导入它们。这是通过将__declspec(dllimport)
放在每个方法的前面来完成的。由于您不能在方法上放置两个前缀,您必须创建两个几乎相同的头文件,这些头文件只是在该方法前缀上有所不同,或者根据这是一个DLL构建代码还是客户端应用程序使用一些宏替换。再一次,您可以在Google中查看它是如何完成的。
我希望有所帮助。