C++ 如何自动注册c++;当这些对象位于单独的共享库中时,是否使用工厂?

C++ 如何自动注册c++;当这些对象位于单独的共享库中时,是否使用工厂?,c++,shared-libraries,registration,factory,C++,Shared Libraries,Registration,Factory,我的情况是,我想创建一个包含工厂的库,让我们称之为FooFactory,对于来自公共基类的派生类,我将其称为IFoo。然后,我有各种各样的对象Foo1、Foo2等,它们是从IFoo派生的,但它们是在单独的共享库中声明的。 当Foo1、Foo2等在同一个库中时,我可以定义静态全局对象initializefo1、initializefo2等,这些对象在其构造函数中向工厂注册该类的create方法。但是,当它们位于单独的库中时,这些初始值设定项对象永远不会实例化,因此派生类永远不会注册。 我以前的

我的情况是,我想创建一个包含工厂的库,让我们称之为FooFactory,对于来自公共基类的派生类,我将其称为IFoo。然后,我有各种各样的对象Foo1、Foo2等,它们是从IFoo派生的,但它们是在单独的共享库中声明的。 当Foo1、Foo2等在同一个库中时,我可以定义静态全局对象initializefo1、initializefo2等,这些对象在其构造函数中向工厂注册该类的create方法。但是,当它们位于单独的库中时,这些初始值设定项对象永远不会实例化,因此派生类永远不会注册。 我以前的研究表明,如果这些库是静态链接的,或者从未使用过,那么初始值设定项可能会被删除,它们的构造函数也不会被调用,但是共享库也是这样吗?如果是这样,是否有某种方法可以确保这些初始化器对象被实例化?最后,如果我只是“把这一切都搞错了”,我当然愿意接受任何关于更好的方法的建议。 我还应该注意到,这个问题似乎是偶然的。在这种情况下,对原始问题的建议答案建议使用这种静态初始值设定项对象,但发问者评论说它不起作用,原因与我所说的相同——初始值设定项从未实例化过——但这个评论基本上没有得到解决。
一些上下文:这一切都发生在Linux机器上,我使用GCC4.7.3进行编译。如果这样做有帮助的话,那么这样做的原因是允许开发人员创建新的派生对象,这些对象可以链接到代码中,而无需修改或重新编译现有的代码库。(新对象是基于运行时事件创建的。)

我使用gcc 4.1.2测试了您在RHEL 5.7上描述的案例,并且在共享库中定义时也会构造全局静态。如果main通过
g++-l lib
选项与共享库链接,那么构造函数会在
main()
之前按预期被调用,并且如果lib是使用
dlopen()
调用手动加载的,那么在加载lib时自然会被构造。但在这两种情况下,它都是自动构建的

无论如何,作为一种解决方法,您可以为共享库定义一个“构造函数”,即加载库时系统调用的函数,并将初始化对象定义为函数中的静态对象?其语法如下所示:

extern "C" {

void __attribute__ ((constructor)) libload(void)
{
    cout << "dll ctor called\n";
    static A a;
}

void __attribute__ ((destructor)) libunload(void)
{
}

} // extern
extern“C”{
void _属性_((构造函数))libload(void)
{

无法清楚您想要什么。工厂是一个创建类(1个或多个)实例的对象/函数。作为工厂允许工厂注册它创建的所有对象。手动调用
register()有什么错
method from every shared object loaded?@DmitryMarkin在我的上下文中这样做是没有意义的,因为我不知道链接到对象时对象的标识。@egur我不太明白你说的是什么。我对工厂的理解是,如果工厂在编译时不知道要创建的对象,他们需要一个方法来向工厂注册自己,这样工厂才能知道如何创建它们。你有什么不同的想法吗?在你的评论的前半部分,我没有得到这个结果。我使用的是Ubuntu 12.04LTS和gcc 4.7.3。我还试着用dlopen()加载,得到了相同的结果(即对象没有实例化).你(或任何人)能建议我如何调试这个吗?如果有帮助,当我在.so库上运行nm时,我得到如下输出:(尽管我还不完全理解这个输出).000000000001b7b8 W_ZN3mlx16NodeAutoRegisterINS_7nodexeec1ev000000000001b7b8 W_ZN3mlx16NodeAutoRegisterINS_7nodexeec2ev这是否意味着符号是正确的,上面的意思是它们实际上在库中(对不起,我对Stackoverflow注释的格式技巧不熟悉)重新调试您可以在ctor中设置一个断点,接受gdb的建议,使其在库加载时挂起,并查看在库加载时是否到达该位置。