我正在使用第三方。我正在使用它的共享库版本,因为库很大(~60MB)并且被多个应用程序使用。
在应用程序启动时是否有办法发现库的发行版/调试版分别用于我的应用程序的发布/调试版本?
更长的说明
公开C ++接口的库。其中一种API方法返回std::vector<std::string>
。
在调试模式下编译应用程序时的问题,应该使用库的调试版本。同样的发布。如果使用了不正确的库版本,应用程序将崩溃。
根据gcc(见http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt03ch17s04.html)
但使用混合模式标准库 这可能是使用调试模式 或release-mode basic_string对象, 事情变得更复杂
P.S。 1
看起来Timbo的提议是一种可能的解决方案 - 使用不同的soname来调试和发布库。那么,应该将什么传递给./configure脚本来更改库的名字?
P.S。 2
我的问题不是在链接时,而是在运行时。
P.S。 3
Here是我正面临的问题。
答案 0 :(得分:7)
引用here的调试模式 nothing 与应用程序的调试或发布版本有关。 STL调试模式使用-D_GLIBCXX_DEBUG
激活,是一种特殊的检查模式。
第三方库实际上不太可能使用STL检查模式进行编译,但如果是,则很可能会很快提及您的代码也应该使用-D_GLIBCXX_DEBUG
进行编译。
如果第三方库没有使用检查STL构建,那么无论您是在进行优化还是调试构建,它都与您的代码兼容。
由于您声明与第3方库的优化版本链接的代码的调试版本导致崩溃,因此该崩溃很可能是由代码中的错误引起的(或者可能是第3方库中的错误)。
Valgrind和GDB是你的朋友。
答案 1 :(得分:5)
我认为您误读了您提供的链接中的文档。特别是,您误解了其目的 - 该部分名为“目标”,并描述了C ++调试库的一些假设设计以及这些设计的后果,以便解释所做出的实际设计选择。您引用的行后面的文本位描述了由假设实现产生的混乱,该实现具有针对发布模式和调试模式字符串的单独设计。它继续说:
因此,我们无法轻松地为std :: basic_string类模板提供安全的迭代器,因为它存在于整个C ++标准库中。
(或者,改写一下,提供一个特殊的“调试”版本的字符串迭代器是不可能的。)
...
使用libstdc ++调试模式的设计,我们无法有效地隐藏用户的调试和释放模式字符串之间的差异。未能隐藏差异可能会导致不可预测的行为,因此我们选择仅执行不需要ABI更改的basic_string更改。对用户的影响预计会很小,因为有简单的替代方案(例如__gnu_debug :: basic_string),并且我们从混合调试和发布编译的翻译单元的能力中获得的可用性好处是巨大的。
换句话说,GCC的libstdc ++中的调试和发布模式的设计已经拒绝了这个假设的实现,并对字符串进行了单独的设计,特别是为了允许您担心如何避免的那种类型的跨模式链接
因此,如果没有-D_GLIBCXX_DEBUG
(或者由于某种原因,如果您愿意的话)编译库,并且将其与应用程序的任一模式相关联,那么您应该没有问题。如果你确实有问题,那是因为某个地方出现了错误。 [但请看下面的编辑!这是std::string
特有的,而不是其他容器!]
修改:在接受此答案后,我在std::vector<std::string> crash处回答了后续问题,并意识到此答案的结论不正确。 GCC的libstdc ++使用字符串来巧妙地支持“Per-use recompilation”(其中给定容器对象的所有使用必须使用相同的标志进行编译,但是在程序中使用相同的容器类不需要使用相同的方法编译flags),但这与提供所需交叉链接能力的完整“单元编译”不同。特别是,文档说明了这种交联能力,
我们认为,如果我们打算提供安全的迭代器,保持程序语义不变,并且在发布模式下不会降低性能,那么这种重新编译水平实际上是不可能的。
因此,如果您在库接口上传递容器,将需要两个单独的库。老实说,对于这种情况,我发现最简单的解决方案就是将两个库安装到不同的目录中(每个变量一个 - 并且您希望两者都与主库目录分开)。或者,您可以重命名调试库文件,然后手动安装。
作为进一步的建议 - 你可能不经常在调试模式下运行它。可能只需要将调试版本静态编译并链接到您的应用程序中,因此您不必担心安装多个动态库并在运行时保持它们直接。
答案 2 :(得分:1)
为DLL的调试版和发行版提供不同的名称,并通过库依赖关系链接正确的版本。除非找到正确的DLL,否则您的应用程序将无法启动。
答案 3 :(得分:0)
这是您应该在构建系统中进行的检查。在您的构建脚本中,
例如,如果您使用的是make:
release: $(OBJ)
$(CC) $(CXXFLAGS_RELEASE) $(foreach LIB,$(LIBS_RELEASE),-l$(LIB))
debug: $(OBJ)
$(CC) $(CXXFLAGS_DEBUG) $(foreach LIB,$(LIBS_DEBUG),-l$(LIB))