2012-08-22 74 views
3

爲了簡單起見,我將DLL_TUTORIAL.dll和頭文件MathFuncsDll.h放在根文件夾C:\中。延遲加載DLL

然後,創建空的項目,設置

配置屬性 - >連接器 - >輸入 - >延遲加載的DLL的

C:\ DLL_TUTORIAL .dll;%(DelayLoadDLLs)

配置屬性> VC++ Directories->包含目錄

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 「/法 」發佈\「/ FO 」發佈\「 /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 @ MathFuncs @@ SAHHH @ Z) 1> C:\用戶\託梅克\文檔\ Visual Studio 2010的\項目\ clean_rough_draft \發佈\ clean_rough_draft.exe:致命錯誤LNK1120:1周無法解析的外部

你能指出我的錯誤?

+2

不支持導出模板方法。你必須把它們放在.h文件中。這留下了一個空的DLL。 –

+0

詳細說明,Template方法不是「真正的」方法 - 它們只是在編譯時用於創建方法的模具。因此模板方法不能編譯成目標代碼。 – nakiya

回答

3

該問題與DLL的延遲加載或沒有任何關係。我可以在這裏看到兩個問題:

  1. 您正在導出模板化函數。這不會以這種方式工作,因爲模板導出在Visual C++編譯器中不受支持,但是已經從標準中刪除。爲此,您有兩種可能的解決方案:

    • 移動.h文件中方法的實現,因此不再需要DLL,因爲所有代碼都在頭文件中;
    • 使用您將在客戶端應用程序中使用的類型實例化模板。這樣做的目的是在你的cpp文件中添加實例化代碼,並在頭文件中執行一些extern template聲明等。你可以在Google上查看更多信息,只需搜索'extern template DLL'或類似的東西即可。
  2. 您只在創建DLL時導出方法,但從不導入它們(或者至少這是我從代碼中看到的)。在每個方法前使用__declspec(dllexport),它告訴編譯器將該方法放入DLL中。當你想從客戶端應用程序使用這些方法時,你必須從DLL中導入它們。這是通過將__declspec(dllimport)放置在每種方法的前面來完成的。既然你不能在這兩個方法上放置兩個前綴,你必須創建兩個幾乎相同的頭文件,這些頭文件只是在方法前綴上有所不同,或者根據這是DLL構建代碼還是客戶端應用程序,使用一些宏替換。再次,您可以在Google中查看它的完成情況。

我希望有幫助。