Вызов статического указателя на список из общей библиотеки в c ++ - PullRequest
0 голосов
/ 05 декабря 2009

У меня есть статический член класса

class bar {...}

class foo {
    public:
        static QHash<qint64,bar>* barRepHash;
}

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

Я инициализирую переменную в основном приложении, но больше не инициализирую ее в разделяемой библиотеке (это казалось ненужным).

Я использую GCC и QT в Ubuntu.

Что происходит и как я могу это исправить?

Ответы [ 2 ]

1 голос
/ 05 декабря 2009

IIRC exe и совместно используемая библиотека получат свои собственные копии статических переменных-членов, подобных этой, и поэтому вам придется инициализировать их отдельно в каждом случае.

Так как это указатель, один из способов может состоять в том, чтобы инициализировать его в вашей основной программе как обычно, а затем передать указатель на dll при загрузке, чтобы версия dll могла указывать на то же место, что и exe один.

EDIT: Хорошо, я провел несколько тестов (Windows, VC9), и оказалось, что глобальные переменные и статические переменные (будь то функция, класс, что угодно) являются для каждого модуля (т.е. каждый exe и dll получат свою собственную копию, даже если переменная пришел из общего источника, как, скажем, статическая библиотека).

Я собираюсь проверить, позволяет ли dllimport / export для класса использовать их общую копию.

EDIT2:

Хорошо, используя __declspec (dllexport) в dll и __declspec (dllimport) в exe (используйте макросы препроцессора для переключения между ними в зависимости от того, что включает в себя заголовок), для объявления статической переменной сделали статическую переменную общей для обоих модулей. Это также работает для глобальных переменных, и я буду предполагать статические переменные функции.

#pragma once

//defined when compiling test.dll
#ifdef TEST_EXPORTS
#define DLL __declspec(dllexport)
#else
#define DLL __declspec(dllimport)
#endif

//foo and bar definition in test.cpp, ie only in the dll's compile
class X
{
public:
    static int foo;
};
DLL extern int bar;

AFAIK GCC, однако, не имеет dllexport и dllimport, однако может иметь какой-то другой способ достижения тех же эффектов при создании общих библиотек (будь то dll или около того).

Если нет, то единственное другое решение, о котором я могу подумать, - это то, что я впервые предложил. Инициализируйте статический указатель в exe, затем в dll есть функция для установки статической переменной, которую exe может вызвать, передав свою копию указателя.

0 голосов
/ 08 января 2010

С помощью атрибутов "section" можно размещать отдельные разделы, кроме data и bss. Только в окнах эти разделы могут быть общими для исполняемого файла с помощью атрибута «shared». На других платформах эта функция не поддерживается. Таким образом, решение будет таким, как упомянуто в предыдущем ответе.

...