作爲庫開發人員,我想阻止我的庫用戶(Windows,MSVC)鏈接到錯誤的配置(而不是將調試庫鏈接到他們的發佈程序,反之亦然)。防止混合調試和發佈庫
是否有可能在編譯期間警告用戶(s)他應鏈接到正確的庫配置?
編輯
Debug和Release版本應可讓Windows開發人員調試他們的應用程序。因此,我的庫的調試版本和發行版本都應該可用。
我在問這個問題,因爲很多對Windows初學者開發人員的支持是由於他們混合了調試和發佈代碼,以及難以調試的運行時錯誤。
作爲庫開發人員,我想阻止我的庫用戶(Windows,MSVC)鏈接到錯誤的配置(而不是將調試庫鏈接到他們的發佈程序,反之亦然)。防止混合調試和發佈庫
是否有可能在編譯期間警告用戶(s)他應鏈接到正確的庫配置?
編輯
Debug和Release版本應可讓Windows開發人員調試他們的應用程序。因此,我的庫的調試版本和發行版本都應該可用。
我在問這個問題,因爲很多對Windows初學者開發人員的支持是由於他們混合了調試和發佈代碼,以及難以調試的運行時錯誤。
您可以添加#warning指令,但我強烈建議您不要這樣做。 您應該更好地以兩種不同的名稱提供給您的圖書館的不同版本。
這裏是你的問題的另一種暗示:
myLib.h // Release Version
myLibd.h // Debug Version
做它喜歡的是,這將迫使用戶照顧時,他們將建立您的圖書館中的應用(因爲設置必須手動) 。
您也可以在自述文件或INSTALL中添加註釋,大多數用戶在想要設置MSVC上的鏈接時閱讀它。
您還可以檢查程序中的DEBUG和NDEBUG宏值。 (在你的庫初始化期間聲明)
好問題,我一直認爲使用我的庫的開發人員會鏈接到正確的版本,現在我想到了,爲什麼你甚至想要發佈你的調試庫?公衆爲何不應同時他們的調試和發佈版本對你的版本庫無論鏈接
,我看到這樣的方式通過出口每個配置一些符號:
//header:
class DLLIMPEXP Dummy
{
static int x;
virtual void dummy();
}
//cpp
#ifdef DEBUG
int Dummy::x = 0;
void Dummy::dummy()
{
}
#endif
,你可以請參閱,如果您的模塊在DEBUG中編譯,則只會導出您的符號。嘗試鏈接到發行版m中的lib來自第三個模塊的代碼會導致鏈接器錯誤。對於相反的情況,你可以有類似的東西。
我不建議你這樣做,但我寧願將其記錄下來,或者只發布我的模塊的發佈版本。
這裏有兩個不同的方面:
如果它的性能問題,則選擇仍然應該是他們的,他們可能希望調試。
如果這是一個不兼容的問題,那麼一件簡單的事情就是更改調試版本的名稱空間,以便符號的修改方式不同。
#ifdef NDEBUG
namespace project {
#else
namespace project { namespace debug {
#endif
// content
#ifdef NDEBUG
}
#else
}
using namespace debug;
}
#endif
通過在debug
命名空間嵌套,你改變的符號是混淆(儘管,編譯明智的,它不會改變任何東西)。這實際上阻止鏈接一個針對調試版本與發佈版本編譯的庫(並因此儘早解決了不兼容問題而不是神祕地崩潰)。
但是,我會敦促你保留這個到一個非常特定的類(它很重)。
通常應該可以在調試和發佈模式下提供兼容接口,以便客戶端可以在加載時進行熱插拔。
將此代碼添加到您的LIB的頭
不同的名稱不同類型
#ifndef _DLL
// C runtime as dll
# ifdef _DEBUG
# pragma comment(lib, "MyLibD.lib")
# else
# pragma comment(lib, "MyLib.lib")
# endif
#else
// C runtime statically
# ifdef _DEBUG
# pragma comment(lib, "MyLibSD.lib")
# else
# pragma comment(lib, "MyLibS.lib")
# endif
#endif
針對不同類型的
#ifndef _DLL
// C runtime as dll
# ifdef _DEBUG
# pragma comment(lib, "debug/dynamic/MyLib.lib")
# else
# pragma comment(lib, "release/dynamic/MyLib.lib")
# endif
#else
// C runtime statically
# ifdef _DEBUG
# pragma comment(lib, "debug/static/MyLib.lib")
# else
# pragma comment(lib, "debug/static/MyLib.lib")
# endif
#endif
不同的路徑之後,你只需要將lib的路徑添加到鏈接器,並且不再是ab把它混合起來。
這通常不被認爲是好的做法(在代碼中指定庫),但它是一個解決方案,所以我不會downvote 。 –
如果你開發一個靜態庫而不是一個DLL,我總是會提供這個。有很多優點和避免錯誤,我不會關心哲學原因。 – Totonga
爲什麼你想讓你的客戶調試你的庫?你是否提供源代碼?設計您的API,以便編譯器設置無關緊要。 COM ABI就是一個很好的例子。 –
如果你創建一個靜態庫而不是一個DLL,你必須以任何方式添加調試版本。否則,沒有人能夠創建調試版本。 – Totonga