Вызов статического указателя на список из общей библиотеки в c ++

StackOverflow https://stackoverflow.com/questions/1851053

Вопрос

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

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".На других платформах эта функция не поддерживается.Таким образом, решение было бы таким, как упоминалось в предыдущем ответе.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top