我现在有点困惑。昨天我有未定义的符号,即使我使用-dynamic与g ++。但现在我没有任何错误,这更令人不安。
为了解释一下我的情况,我想做一些像共享对象这样的插件。我还没有决定哪种方法最好。
A)我的共享对象都有一个名为register的函数,它将使用参数调用。这将是一个插件管理器。
B)我的共享对象将定义一个类,并在加载时创建该类的实例。在该类的构造函数中,它将尝试从应用程序中获取静态单例并自行注册。
据我所知,我的第一次尝试到目前为止并不是那么大。
的main.cpp
#include "main.hpp"
#include <iostream>
#include <cstdio>
#include <dlfcn.h>
int S::shared = 0;
int main(int argc, char** argv){
std::cout << "In main -> " << S::shared << "\n";
void* triangle = dlopen("./libtwo.so", RTLD_LAZY);
if(triangle == NULL){
std::cout << "Error while loading so file\n" << dlerror() << "\n";
}
std::cout << "In main -> " << S::shared << "\n" << triangle;
return 0;
}
main.hpp
class S {
public:
static int shared;
S(){
S::shared = 0;
};
};
two.cpp
#include "main.hpp"
#include <iostream>
class MyObject {
public:
MyObject(){
std::cout << "In two -> " << S::shared << "\n";
}
};
MyObject t();
在该示例中,S :: shared是我将共享的静态对象。对于这个简单的测试,我只使用int,但在未来它将是一个类的实例。
我在案例A中的唯一尝试是段错误......我真的不知道我错过了什么。
//到目前为止的结果(今天)
piplup@vika:~/dev/WebDesign/Scproci$ scons -Q
g++ -o two.os -c -fPIC two.cpp
g++ -o libtwo.so -shared two.os
g++ -o main.o -c -fPIC main.cpp
g++ -o main -Wl,--export-dynamic main.o -ldl
piplup@vika:~/dev/WebDesign/Scproci$ ./main
In main -> 0
In main -> 0
答案 0 :(得分:1)
#include "main.hpp"
#include <iostream>
class MyObject {
public:
MyObject(){
std::cout << "In two -> " << S::shared << "\n";
}
};
MyObject* t;
__attribute__((constructor))
void init_two()
{
t = new MyObject();
}
__attribute__((destructor))
void uninit_two()
{
delete t;
}
这应该产生预期的结果。使用指针,因为在共享对象中显式处理它们更容易,因为常规初始化不会自动发生。如果您不想使用指针,请为您的类提供显式初始化,并在共享库初始化函数中调用它。
*编辑*
我做了一些额外的实验,看来如果你使用默认构造函数,请隐式使用它,如果你正常使用非默认构造函数,它将被调用。
所以你可以改变你的:
MyObject t();
致电:
MyObject t;
并且在没有定义显式初始化函数的情况下工作。
或
class MyObject {
public:
MyObject() { /* as before */ };
MyObject(int val)
{
S::shared = val;
std::cout << "In two -> " << S::shared << "\n";
}
};
MyObject t(10);
似乎编译器对MyObject是否();是全局范围内的变量声明或函数声明,并将其视为函数声明。
答案 1 :(得分:0)
立刻跳到我身边的问题是你必须分开链接单元。静态类成员只是包含在该类的命名空间中的全局。
现在,如果您有两个链接单元,比如主程序和共享对象,那么它们很可能都具有全局foo
,并且它们将是不同的值。
另外,为什么two.cpp中的t的静态初始化没有在共享对象中运行,为什么不清楚,它可能不会保证在共享对象中某种类型的main函数之前发生。