我正在使用一些静态库构建我的程序(实际测试) 这个库包含一个文件,我在其中有这样的函数:
string& GetString() {
static string strFilename;
return strFilename;
}
void PrintToScreen() {
printf("String: %s\n", GetString().c_str())
}
然后在我的main.cpp(库外)我正在做:
GetString() = "abc";
printf("String: %s\n", GetString().c_str());
PrintToScreen();
我得到了这个输出:
String: abc
String:
所以看起来像第二次调用函数
(但是从不同的文件中完成,这是在库内)
以某种方式清除以前的值,重新初始化它,或者使用它自己的副本
我更改了GetString函数以使用'new'但结果完全相同(顺便说一下。程序永远不会崩溃)
但是我不明白它有可能吗?
我有什么不妥的想法吗?
-------------------------------更新--------------- ---------------
0000000000000030 T _Z16GetLogprintfFilev
0000000000000008 b _ZGVZ16GetLogprintfFilevE16strLogprintfFile
0000000000000018 b _ZZ16GetLogprintfFilevE16strLogprintfFile
U _Z16GetLogprintfFilev
并且在我的基础库上使用nm(由最终的lib使用),我得到:
0000000000000030 T _Z16GetLogprintfFilev
0000000000000008 b _ZGVZ16GetLogprintfFilevE16strLogprintfFile
0000000000000018 b _ZZ16GetLogprintfFilevE16strLogprintfFile
答案 0 :(得分:3)
是的,静态链接很可能。
示例:
libA.a // contains GetString()
// Contains. PrintToScreen()
// Here the reference has been resolved.
libX.so // Contains a call to GetString()
// This library is linked with libA.a
// Thus pulls in the function GetString() into this library.
libY.so // Contains a call to PrintToScreen()
// This library is linked with libA.a
// Thus pulls in the function PrintToScreen and GetString() into this library.
a.out // linked against libY.so libX.so
// This has two distinct versions of GetString()
在上面的例子中,如果a.out包含一个调用getString(),则它是特定于操作系统的,将调用哪个版本的getString()。在大多数系统中,使用单个共享库的加载顺序,但在其他系统上,它将对共享库进行深度优先搜索(即,lib X加载XA XB,Y加载YA YB。搜索顺序可以是X XA XB Y YA YB或XY XA XB YA YB)。您需要查阅每个OS共享库文档,以了解在运行时如何搜索符号。
这里的解决方案是仅链接共享库(在大多数情况下是默认值) 这样你只能获得一个libA副本(假设你使libA成为一个共享库)并且它的内容只加载到运行时一次(没有副本)。
注意:这不是语言层面的失败 这是由链接引起的失败,超出了C / C ++语言的范围。
答案 1 :(得分:-1)
实际上在一个例子中有一个缺失的想法。它应该是这样的:
string& GetString() {
static string strFilename;
return strFilename;
}
extern "C" {
void PrintToScreen() {
printf("String: %s\n", GetString().c_str())
}
}
奇怪。无论如何,我重构了这样的事情:
extern "C" {
string* GetString() {
static string strFilename;
return &strFilename;
}
void PrintToScreen() {
printf("String: %s\n", GetString()->c_str())
}
}
现在它没有问题。
我似乎很奇怪编译器没有抱怨。
感谢所有人的贡献,问题现在已经解决了。
---------------------------------- EDIT ------------ ----------------------
我后来再次遇到这个问题,所以这不是正确的解决方法 真正的问题是一些初始化的单身人士 在此期间,并在类构造函数中:
GetString() = "";
所以,问题很简单,但很难追踪......