Вызов статического указателя на список из общей библиотеки в c ++
Вопрос
У меня есть статический член класса
class bar {...}
class foo {
public:
static QHash<qint64,bar>* barRepHash;
}
Теперь я вызываю функцию, которая обращается к этому элементу в общей библиотеке, я получаю сообщение об ошибке памяти, тогда как когда я обращаюсь к функции через основную программу, она работает нормально.Я проверял это при ряде обстоятельств.
Я инициализирую переменную в основном приложении, но я не инициализирую ее снова в общей библиотеке (это казалось ненужным).
Я использую GCC и QT в Ubuntu.
Что происходит и как я могу это исправить?
Решение
IIRC exe и разделяемая библиотека получат свои собственные копии статических переменных-членов, подобных этому, и поэтому вам нужно будет инициализировать их отдельно в каждом случае.
Поскольку это указатель, одним из способов может быть инициализация его в вашей основной программе как обычно, а затем передача указателя на dll при ее загрузке, чтобы версия dll могла указывать на то же место, что и версия exe.
Редактировать:Хорошо, я провел несколько тестов (Windows, VC9), и оказалось, что глобальные и статические переменные (будь то функция, класс, что угодно) относятся к каждому модулю (т. е.каждый exe-файл и dll получит свою собственную копию, даже если переменная взята из общего источника, например, из статической библиотеки).
Я собираюсь протестировать, чтобы увидеть, заставляет ли dllimport / export в классе использовать общую копию.
РЕДАКТИРОВАТЬ 2:
Хорошо, используя __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 может вызывать, передавая свою копию указателя.
Другие советы
С помощью "раздела" атрибуты могут быть размещены в определенных разделах отдельно от данных и bss.Только в Windows эти разделы могут быть общими для всех исполняемых файлов с помощью атрибута "shared".На других платформах эта функция не поддерживается.Таким образом, решение было бы таким, как упоминалось в предыдущем ответе.