#c #global-variables #solaris #shared-libraries
#c #глобальные переменные #solaris #разделяемые библиотеки
Вопрос:
У меня проблема с глобальными переменными в разделяемой библиотеке Solaris. Рассмотрим следующий пример:
class Foo
{
public:
Foo() { Init(); }
private:
void Init() { // do something }
};
У меня есть некоторый код в разделяемой библиотеке:
Foo g_Foo;
Я заметил, что Foo constructor никогда не вызывается в Solaris, в то время как тот же код работает в Linux.
Я использую gcc 3.4.3 и Sun linker.
Комментарии:
1. Не могли бы вы опубликовать весь код того, что на самом деле вы делаете? Я не думаю, что есть проблема с ОС.
2. Я поддержу это. В прошлом я часто использовал эту идиому в Solaris, и она всегда работала. (По общему признанию, я обычно компилирую с использованием Sun CC, но я действительно не думаю, что проблема в g .)
3. Вы уверены, что это тот сценарий. Опубликованный вами код кажется прекрасным. Но упомянутое вами поведение заставляет меня предположить «фиаско статической инициализации», хотя в опубликованном вами коде об этом не говорится.
4. Я работаю над переносом некоторого кода на Solaris. Я могу воспроизвести проблему в примере выше. Еще одно замечание — в том же коде, скомпилированном как статическая библиотека, этой проблемы нет. Это можно решить, изменив Init на общедоступный и вызвав его из функции инициализации библиотеки (-z initarray=init_lib), но это применимо не во всех случаях
5. Вы уверены, что ваша библиотека загружается? Я видел проблемы, в которых
env
была допущена ошибка и загружена более старая версия разработки.so
, или когда существуют статическая и динамическая версии библиотеки, и она компилируется с неправильной. Я был вдали от solaris достаточно долго, чтобы забыть некоторые команды, но вы можете запустить команду в исполняемом файле, чтобы посмотреть, какие библиотеки будут использоваться при ее запуске (она выводит полную информацию о пути для каждой.so
)
Ответ №1:
Вы создаете общий объект с флагом -G? например, CC -G -o mylib.so myfile.cpp
Если вы не укажете -G, то компилятор может неправильно инициализировать глобальные переменные. Смотрите документацию компилятора здесь.
Обратите внимание, в документах также говорится, что вы не можете использовать ld, но вам нужно использовать CC для создания ссылок.