我一直致力于一些已建立的C ++项目,这些项目使用来自共享库的静态变量来存储参数。使用g++
或clang++
进行编译时,静态变量在整个程序中共享(具有相同的内存位置)。但是,使用Xcode编译时,main
函数静态变量具有与共享库静态变量不同的内存位置。有没有办法让Xcode编译/运行与g++
或clang++
相同的代码,同时仍然能够使用Xcode进行调试?
请参阅以下示例:
main.cpp中:
#include <iostream>
#include "Params.hpp"
int main(int argc, const char * argv[]) {
Params param = Params();
param.addParams();
std::vector<int> vi = Params::ParamsObj();
vi.push_back(10);
for(std::vector<int>::iterator it = vi.begin(); it != vi.end(); ++it) {
std::cout << "i = " << *it << std::endl;
}
return 0;
}
Params.hpp:
#ifndef Params_hpp
#define Params_hpp
#include <vector>
class Params{
typedef std::vector<int> ParamVector;
public:
static ParamVector& ParamsObj() {
static ParamVector m;
return m;
}
void addParams();
};
#endif /* Params_hpp */
Params.cpp:
#include "Params.hpp"
void Params::addParams(){
Params::ParamsObj().push_back(5);
}
生成文件:
clang:
clang++ -dynamiclib Params.cpp -o libshared_clang.dylib
clang++ main.cpp -o main_clang ./libshared_clang.dylib
gpp:
g++-mp-4.9 -Wall -shared -fPIC -o libshared_gpp.so Params.cpp
g++-mp-4.9 -Wall -o main_gpp main.cpp ./libshared_gpp.so
g++
和clang++
的输出为:
i = 5
i = 10
Xcode只输出i = 10
。
如果我不使用共享库并将所有内容编译成一个二进制文件,Xcode将正确输出两个print语句。
我目前的解决方案是将项目的main
函数添加到自己的共享库中,然后创建一个Xcode特定文件,该文件仅调用新创建的共享库中的main
函数。但是,我希望找到一个不需要更改底层项目代码的解决方案。
答案 0 :(得分:1)
我很确定如果你打开gcc / clang的优化(你在你的例子中没有),它们将产生与使用XCode编译相同的行为(这不是编译器,但是IDE)。
你的问题是ParamsObj()
函数是内联的(在类体中定义它添加一个隐式的inline
关键字),允许编译器只是粘贴&#34;它进入main
方法而不是调用它。
对于dll边界,如果函数在多个库中使用(在您的情况下,它在dll中使用,并内联到主可执行文件中),这可能会导致分配多个静态变量。 / p>
将ParamsObj()
方法重构为相应C ++文件中的声明和单独定义,并且您将在任何地方获得相同的行为,打印这两个数字。