开发者

Using objects of an app from shared object

I'm a little confused right now. Yesterday I had undefined symbols even if I used -rdynamic with g++. But now I don't have any error and that is even more disturbing.

To explain a bit my case, I want to do some sort of plugin like shared object. I haven't decided yet which is the best way to do.

A) My shared objects all have a function called register which will be called with a parameter. This will be a plugin manager.

B) My shared object will define a class and will create and instance of that class at load time. In the constructor of that class it will try to get a static singleton from the app and auto register himself.

As far as I can tell my first attempts weren't so great so far.

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();

In that sample S::shared is the static object I would share. For this simple test I only use a int but in the futur it would be an instance of a class.

My only attempt at case A) was a segfault... I really don't know what I missed.

//Results so far (today)

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


#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;
}

This should produce what is expected. Pointers are used as it is easier to deal with them explicitly in shared objects as regular initialization doesn't happen automatically. If you don't want to use the pointers provide an explicit initialization for your class and call it in the shared library initialzation function.

* EDIT *

I did some additional experimentation and it appears that if you are using the default constructor, use it implicitly and it will be called, if you are using a non-default constructor then as normal.

so you could change your:

MyObject t();

call to:

MyObject t;

and it wil work without the explicit initialization functions being defined.

or

class MyObject {
public:
   MyObject() { /* as before */ };
   MyObject(int val)
   {
        S::shared = val;
        std::cout << "In two -> " << S::shared << "\n";
   }
};

MyObject t(10);

It appears that the compiler gets confused as to whether the MyObject t(); is a variable declaration, or a function declaration at the global scope and treats it as a function declaration.


The problem that immediately jumps at me is that you have to separate link units. A static class member is just a global wrapped up in the namespace of that class.

Now, if you have two link units, say you main program and shared object, it is quite possible for both of them to have a global foo, and they would be distinct values.

Also, why the static initialization of t in two.cpp is not run in a shared object is not clear, its probably not guaranteed to happen before some type of main function in the shared object.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜