2011-10-12 53 views
6

作为库开发人员,我想阻止我的库用户(Windows,MSVC)链接到错误的配置(而不是将调试库链接到他们的发布程序,反之亦然)。防止混合调试和发布库

是否有可能在编译期间警告用户(s)他应链接到正确的库配置?

编辑

Debug和Release版本应可让Windows开发人员调试他们的应用程序。因此,我的库的调试版本和发行版本都应该可用。

我在问这个问题,因为很多对Windows初学者开发人员的支持是由于他们混合了调试和发布代码,以及难以调试的运行时错误。

+0

为什么你想让你的客户调试你的库?你是否提供源代码?设计您的API,以便编译器设置无关紧要。 COM ABI就是一个很好的例子。 –

+0

如果你创建一个静态库而不是一个DLL,你必须以任何方式添加调试版本。否则,没有人能够创建调试版本。 – Totonga

回答

0

您可以添加#warning指令,但我强烈建议您不要这样做。 您应该更好地以两种不同的名称提供给您的图书馆的不同版本。

这里是你的问题的另一种暗示:

myLib.h // Release Version 
myLibd.h // Debug Version 

做它喜欢的是,这将迫使用户照顾时,他们将建立您的图书馆中的应用(因为设置必须手动) 。

您也可以在自述文件或INSTALL中添加注释,大多数用户在想要设置MSVC上的链接时阅读它。

您还可以检查程序中的DEBUG和NDEBUG宏值。 (在你的库初始化期间声明)

4

好问题,我一直认为使用我的库的开发人员会链接到正确的版本,现在我想到了,为什么你甚至想要发布你的调试库?公众为何不应同时他们的调试和发布版本对你的版本库无论链接

,我看到这样的方式通过出口每个配置一些符号:

//header: 
class DLLIMPEXP Dummy 
{ 
    static int x; 
    virtual void dummy(); 
} 
//cpp 
#ifdef DEBUG 
int Dummy::x = 0; 
void Dummy::dummy() 
{ 
} 
#endif 

,你可以请参阅,如果您的模块在DEBUG中编译,则只会导出您的符号。尝试链接到发行版m中的lib来自第三个模块的代码会导致链接器错误。对于相反的情况,你可以有类似的东西。

我不建议你这样做,但我宁愿将其记录下来,或者只发布我的模块的发布版本。

+0

非常有趣。你有一个想法:添加将在库中的非内联函数IsReleaseVersion()。并添加构造函数内联检查(将包含在应用程序端)以检查其版本。 – Phong

+0

我刚刚编辑了这个问题来回答你的一些问题。 仅当用户尝试在自己的代码中使用该符号时,才会触发链接错误。此外,我希望用户得到一个明确的信息,告诉他们“你没有链接到正确的图书馆”。 – Mourad

+0

@Mourad:您可以将缺少的符号命名为PleaseUseReleaseVersionOfXxxLibrary,同样请PleaseUseDebugVersionOfXxxLibrary。 –

1

这里有两个不同的方面:

  • 不兼容的问题
  • 性能问题

如果它的性能问题,则选择仍然应该是他们的,他们可能希望调试。

如果这是一个不兼容的问题,那么一件简单的事情就是更改调试版本的名称空间,以便符号的修改方式不同。

#ifdef NDEBUG 
    namespace project { 
#else 
    namespace project { namespace debug { 
#endif 

// content 

#ifdef NDEBUG 
    } 
#else 
    } 
    using namespace debug; 
    } 
#endif 

通过在debug命名空间嵌套,你改变的符号是混淆(尽管,编译明智的,它不会改变任何东西)。这实际上阻止链接一个针对调试版本与发布版本编译的库(并因此尽早解决了不兼容问题而不是神秘地崩溃)。

但是,我会敦促你保留这个到一个非常特定的类(它很重)。

通常应该可以在调试和发布模式下提供兼容接口,以便客户端可以在加载时进行热插拔。

0

将此代码添加到您的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把它混合起来。

+1

这通常不被认为是好的做法(在代码中指定库),但它是一个解决方案,所以我不会downvote 。 –

+0

如果你开发一个静态库而不是一个DLL,我总是会提供这个。有很多优点和避免错误,我不会关心哲学原因。 – Totonga