Привет Dmitry!
16 Oct 04 10:20, Dmitry Ponyatov писал Alex Mogilnikov:
DP> про переопределение new и delete я уже где-то читал и меня это не DP> слишком беспокоит, но есть же еще всякие навороты типа таблиц DP> виртуальных методов, для руления которыми нужен свой код ?
Что ты понимаешь под рулением таблицами? Здесь компилятор все делает сам - и таблицы сооставляет, и нужные адреса из них выбирает когда надо. Я никогда "руками" (то есть из ассемблерных модулей) виртуальные методы объектов не звал.
AM>> Покажи как ты в своем стартапе вызываешь AM>> конструкторы глобальных объектов.
DP> class BZZ { [ skip ] DP> void main() DP> { DP> // инициализация и возьня с железом DP> }
Так это не стартап.
DP> кажется понял в чем ошибка: main вызываю своим ассемблерным кодом, DP> поэтому даже если компилер и создал вызов конструкторов, я их обхожу
Вот этот ассемблерный (как правило, но бывают исключения) модуль и есть стартап. Именно его я и хотел увидеть. Hу, раз выяснилось, что проблема именно в нем, расскажу, как должны вызываться конструкторы и деструкторы глобальных объектов (у меня в свое время тоже были с этим трудности, но почему-то никто не смог объяснить, пришлось разбираться самому). Сразу оговорюсь, нижеописанное справедливо для gcc3. Hе уверен, что это же справедливо для gcc2.
В каждом С++ модуле, где определяются глобальные объекты, имеющие конструкторы, компилятор генерит код вызова этих конструкторов и помещает указатель на точку входа в этот код инициализации в секцию .ctors. Аналогично генерится код вызова глобальных деструкторов и указатель на точку входа в него помещается в секцию .dtors. В стартапе ты должен вызвать код для всех этих модулей. Обычно это делается с помощью модулей crtbegin и crtend, например таких:
=========== crtbegin.c ========== typedef void (*fptr)(void);
static fptr ctor_list[1] __attribute__((section(".ctors"))) = { (fptr) -1 }; static fptr dtor_list[1] __attribute__((section(".dtors"))) = { (fptr) -1 };
void do_ctors(void) { fptr *fpp;
for(fpp = ctor_list + 1; *fpp != 0; ++fpp) ; while(--fpp > ctor_list) (**fpp)(); }
void do_dtors(void) { fptr *fpp;
for(fpp = dtor_list + 1; *fpp != 0; ++fpp) (**fpp)(); } ================================= ============ crtend.c =========== typedef void (*fptr)(void);
static fptr ctor_end[1] __attribute__((section(".ctors"), __unused__)) = { 0 }; static fptr dtor_end[1] __attribute__((section(".dtors"), __unused__)) = { 0 }; =================================
В линкерном скрипте секции .ctors и .dtors должны быть собраны таким образом, чтобы первым оказался crtbegin, последним crtend, а все остальное между ними, например так:
.ctors : { KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors)) /* все кроме crtend.o */ KEEP (*(.ctors)) /* оставшийся crtend.o */ } .dtors : { KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors)) KEEP (*(.dtors)) }
Дальше, надеюсь, объяснения излишни. Остается только в стартапе перед вызовом main() позвать do_ctors(), а после завершения main() - do_dtors(). Hаверняка в используемых тобой библиотеках вышеприведенное уже есть в том или ином виде, посмотри внимательно.
DP> по активному использованию ООП вопрос остается открытым -- нужны URLы DP> примеров таких проектов
Может лучше хорошую книжку с примерами почитать? Я литературу советовать не берусь, сам далеко не гуру... :) Хотя вот "С++ for Real Programmers" Элджера мне понравилась...
DP> PS: для сборки использую gcc, примеры взял из фака os.development на DP> megatokio
Всего наилучшего, [Team PCAD 2000] Алексей М. ... Пирожок печеный с печенью.