2011-12-19 96 views
0

我使用Visual Studio Express 2010鏈接靜態成員從DLL的一個奇怪的問題。在Linux平臺 和MSYS/MinGW(GCC)不會發生此故障。從dll鏈接靜態成員

我已經使用導出宏觀明確地爲這個圖書館模塊數學庫:

#ifdef WIN32 
    #ifdef MATH_LIBRARY_EXPORT 
    #define MATH_LIBRARY_API __declspec(dllexport) 
    #else 
    #define MATH_LIBRARY_API __declspec(dllimport) 
    #endif 
#else 
    //define empty values for linux OS 
    #define MATH_LIBRARY_API 
#endif 

,這是一個剪斷我的Vector類的我出口與靜態成員:

ifndef BINREV_VECTOR_H__ 
#define BINREV_VECTOR_H__ 

// include common header with dll import/export macro 
#include <brMath/brCommons.h> 

namespace binrev{ 
namespace brMath{ 

class MATH_LIBRARY_API brVector3f 
{ 
    public: 
    float m_fX, m_fY, m_fZ; 

    brVector3f(void); 
    brVector3f(float x, float y, float z); 

    ... 

    public: 
    static const brVector3f ZERO; 
    static const brVector3f NEGATIVE_UNIT_Z; 
    ... 
}; 

而且cpp模塊:

// Ensure that the dll hader will be exported 
#define MATH_LIBRARY_EXPORT 
#include <brMath/brVector3f.h> 

namespace binrev{ 
namespace brMath{ 

const brVector3f brVector3f::ZERO(0.0f, 0.0f, 0.0f); 
const brVector3f brVector3f::NEGATIVE_UNIT_Z(0.0f, 0.0f, -1.0f); 

... 

在我的圖形模塊(也是一個不同的顯式e XPORT宏)使用這個數學DLL我試圖訪問這些靜態的成員之一:

#include <brMath/brVector3f.h> 

brMath::brVector3f brCamera::getDirection(void) 
{ 
    return m_orientation.rotate(brMath::brVector3f::NEGATIVE_UNIT_Z); 
} 

在其他平臺上的任何運作良好,但與2010年MVSE我得到 一個連接失敗:

1>------ Erstellen gestartet: Projekt: ZERO_CHECK, Konfiguration: Debug Win32 ------ 
2>------ Erstellen gestartet: Projekt: brGraphics, Konfiguration: Debug Win32 ------ 
2> brCamera.cpp 
2>brCamera.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""public: static class binrev::brMath::brVector3f const binrev::brMath::brVector3f::NEGATIVE_UNIT_Z" ([email protected]@[email protected]@@[email protected]B)". 
2>C:\binrev\repository\binrevengine\modules\brGraphics\trunk\bin\brGraphics.dll : fatal error LNK1120: 1 nicht aufgelöste externe Verweise. 
========== Erstellen: 1 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ========== 

我不是MVSE的朋友,這是我第一次嘗試讓我們的代碼可以與MVSE一起運行。雖然我有不同的解決方案,但我在項目設置中添加了brMath.lib作爲附加依賴項。我還將附加庫目錄的路徑設置爲我的brMath.lib的位置。這是連接器的命令的輸出爲我設置的回顧:

/OUT:"C:\binrev\repository\binrevengine\modules\brGraphics\trunk\bin\brGraphics.dll" /INCREMENTAL /NOLOGO 
/LIBPATH:"C:\binrev\repository\binrevengine\modules\brMath\trunk\lib\Debug" /DLL "kernel32.lib" "user32.lib" "gdi32.lib" 
"winspool.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "comdlg32.lib" "advapi32.lib" "brCore.lib" "brMath.lib" 
"c:\binrev\development\vs2010\VC\lib\libboost_signals-vc100-mt-gd-1_47.lib" "c:\binrev \development\vs2010\VC\lib\libboost_system-vc100-mt-gd-1_47.lib" 
/MANIFEST /ManifestFile:"brGraphics.dir\Debug\brGraphics.dll.intermediate.manifest" /ALLOWISOLATION 
/MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"C:\binrev\repository \binrevengine\modules\brGraphics\trunk\bin\brGraphics.pdb" 
/SUBSYSTEM:CONSOLE /STACK:"10000000" /PGD:"C:\binrev\repository\binrevengine\modules\brGraphics\trunk\bin\brGraphics.pgd" /TLBID:1 
/DYNAMICBASE /NXCOMPAT /IMPLIB:"C:/binrev/repository/binrevengine/modules/brGraphics /trunk/lib/Debug/brGraphics.lib" /MACHINE:X86 /ERRORREPORT:QUEUE 

似乎過於我,什麼是正確鏈接。當我刪除brVector3f的const static dll成員的調用時,構建是成功的。我認爲const static成員一定有問題。但是爲什麼只有在MVSE中才能進入地獄?

我找不到這個引種任何區別:http://stackoverflow...c-data-in-a-dll 所以通常應該是工作...

現在我跑出來的想法可能是錯誤的。 我很感激任何幫助或暗示。

+2

您聲明'NEGATIVE_UNIT_X'但定義了'UNIT_X'。這是一個錯字嗎? – Baltram 2011-12-19 13:42:59

+0

Yepp這是一個複製和粘貼失敗,對不起。正確的定義是brVector3f brVector3f :: NEGATIVE_UNIT_Z(0.0f,0.0f,-1.0f); – Hellhound 2011-12-19 15:27:46

回答

1

「...在文件範圍修改變量或函數時,static關鍵字指定變量或函數具有內部鏈接(其名稱在聲明它的文件外部不可見)。」 from MSDN

+0

基本上是這樣,但我發現有幾個消息來源說,如果我使用導入/導出宏,這個導出應該是可能的: http://www.gamedev.net/topic/498607-problem-w-static-const -member-variable-in-dll/ 我也檢查了一些開源項目,即Ogre和我見過那些項目使用這種機制。但我不確定這些項目是否支持MVSE 2010,新MVSE是否可能更具限制性? – Hellhound 2011-12-20 11:25:00

+1

這裏引用的靜態變量不在文件範圍內:它在類範圍內。它在聲明文件的外部是可見的,但每個類只有一個變量,而不是每個對象一個變量。 我不知道DLL的一面...... – Zero 2012-09-13 07:52:33