Использование объектов приложения из общего объекта - PullRequest
0 голосов
/ 22 августа 2011

Я сейчас немного растерялся. Вчера у меня были неопределенные символы, даже если я использовал -rdynamic с 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, но в будущем это будет экземпляр класса.

Моя единственная попытка в случае А) была сегфо ... Я действительно не знаю, что я пропустил.

// Результаты на сегодня (сегодня)

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

Ответы [ 2 ]

1 голос
/ 22 августа 2011
#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 t (); является объявлением переменной или объявлением функции в глобальной области видимости и обрабатывает его как объявление функции.

0 голосов
/ 22 августа 2011

Проблема, которая сразу бросается в глаза, заключается в том, что вам нужно разделить блоки ссылок. Член статического класса - это просто глобальный элемент, заключенный в пространство имен этого класса.

Теперь, если у вас есть два блока ссылок, скажем, ваша основная программа и общий объект, вполне возможно, что они оба имеют глобальный foo, и они будут разными значениями.

Кроме того, почему статическая инициализация t в two.cpp не выполняется в совместно используемом объекте, неясно, вероятно, она не гарантированно произойдет до некоторого типа главной функции в совместно используемом объекте.

...