*** ВНИМАНИЕ: Блог переехал на другой адрес - demin.ws ***

четверг, 16 июня 2011 г.

Динамическая линковка C++ на AIX

AIX мне всегда нравился своим особо изощренным отношением к линковке.

Итак, рассмотрим пример (система AIX 5.3).

Файл "alib.cpp" компилируем как динамическую библиотеку.

struct A {
  A() {
    value_ = 123;
  }
  int value_;
};

A a = A();

extern "C"
int value() {
  return a.value_;
}

В этой библиотеке создается статический объект класса А, и значение его поля возвращается функцией "value()".

Компилируем:

xlC -o alib.so -qrtti=all -qmkshrobj=-100 -G -brtl -bnolibpath alib.cpp

"xlC" - это компилятор С++ на AIX.

Далее, файл "main.c". Это головной модуль на С, который вызывает функцию "value()".

extern int value();

int main() {
  return value();
}

Этот модуль вызывает "value()", и значение становится кодом возврата процесса.

Компилируем:

xlc -c -o main.o main.c

"xlc" (маленькая "с" на конце) - это компилятор С на AIX.

Линкуем, используя компилятор "С", запускаем и печатаем код возврата ($?):

xlc -o main main.o alib.so && LIBPATH=.:$LIBPATH ./main ; echo $?

Результат на экране:

0

Интересно?! Почему не ожидаемое 123?

Теперь линкуем, используя компилятор "С++", запускаем и печатаем код возврата:

xlC -o main main.o alib.so && LIBPATH=.:$LIBPATH ./main ; echo $?

Результат на экране:

123

Мораль: на AIX, при динамической линковке библиотек, чтобы правильно работала статическая инициализация на С++, надо принудительно линковать конечный бинарь в режиме С++ (как бы это странно не звучало). Иначе конструкторы статических объектов вызваны не будут, и их инициализация будет произведена не ДО функции "main()", а непонятно когда.

Можно принудительно заставить таки систему вызвать конструкторы статических объектов, написав что-то вроде:

#include <dlfcn.h>

static int module_initialised = 0;
static void ManualInitilizationForStatics() {
  if (module_initialised) return;
  dlopen("blah.so", RTLD_NOW);
  module_initialised = 1;
}

Но это не программирование, а ерзанье.

Комментариев нет:

Отправить комментарий