Разделяемые библиотеки Solaris и глобальные переменные

#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 для создания ссылок.