Отключил CRT, не вызывается конструктор у глоб. объектов

Тема в разделе "LANGS.C", создана пользователем Rustem, 6 сен 2007.

  1. Rustem

    Rustem New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2004
    Сообщения:
    429
    Адрес:
    Russia
    В общем сабж...Хотел поизвращаться на С++, писать маленький код, а тут столько подводных камней)
    Как вызвать конструктор? или сделать свой new?
     
  2. 10110111

    10110111 New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2006
    Сообщения:
    319
    Адрес:
    Санкт-Петербург
    IMHO, проще написать свою CRT с учётом требования малого объёма кода... или вообще делать всё а-ля C.
     
  3. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    http://www.wasm.ru/forum/viewtopic.php?id=22395
     
  4. maxdiver

    maxdiver Max

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    308
    Адрес:
    Саратов
    Например, можно сделать так:

    Код (Text):
    1. #include "libcpptiny.h"
    2. #include <windows.h>
    3.  
    4.  
    5. // //////////////////////////////////////////////
    6. // Function definitions
    7.  
    8. // Initialization
    9.  
    10. //! All initializations (atexit table, constructors)
    11. void cpplibtiny_init();
    12. //! C++ initializers (constructors) call
    13. void cpplibtiny_call_constructors();
    14.  
    15. // Deinitialization
    16.  
    17. //! All deinitializations (destructors, atexit list)
    18. void cpplibtiny_deinit();
    19. //! Terminators call
    20. void cpplibtiny_call_terminators();
    21. //! Deinitialization of atexit list
    22. void cpplibtiny_destroy_atexit_table();
    23.  
    24. // Utilities
    25.  
    26. //! Pointer to a function
    27. typedef void (__cdecl * cpplibtiny_funcptr) ();
    28. //! Pointer to a function
    29. typedef int (__cdecl * cpplibtiny_funcptr_int) ();
    30. //! Calls all functions from the table
    31. void cpplibtiny_call_func_table (
    32.     cpplibtiny_funcptr * begin, cpplibtiny_funcptr * end);
    33. //! Calls all functions from the table in a reverse order
    34. void cpplibtiny_call_func_table_rev (
    35.     cpplibtiny_funcptr * begin, cpplibtiny_funcptr * end);
    36.  
    37.  
    38. // //////////////////////////////////////////////
    39. // Data
    40.  
    41. // C++ initializers
    42. #pragma data_seg(".CRT$XCA")
    43. static cpplibtiny_funcptr
    44.     cpplibtiny_init_begin[] = { 0 };
    45. #pragma data_seg(".CRT$XCZ")
    46. static cpplibtiny_funcptr
    47.     cpplibtiny_init_end[] = { 0 };
    48. #pragma data_seg()
    49.  
    50. // Terminators (atexit table)
    51. static cpplibtiny_funcptr
    52.     * cpplibtiny_term_begin,
    53.     * cpplibtiny_term_end;
    54.  
    55.  
    56. // //////////////////////////////////////////////
    57. // Initialization
    58.  
    59. void cpplibtiny_init()
    60. {
    61.     cpplibtiny_call_constructors();
    62. }
    63.  
    64. void cpplibtiny_call_constructors()
    65. {
    66.     cpplibtiny_call_func_table (cpplibtiny_init_begin, cpplibtiny_init_end);
    67. }
    68.  
    69.  
    70. // //////////////////////////////////////////////
    71. // Deinitialization
    72.  
    73. void cpplibtiny_deinit()
    74. {
    75.     cpplibtiny_call_terminators();
    76.     cpplibtiny_destroy_atexit_table();
    77. }
    78.  
    79. void cpplibtiny_call_terminators()
    80. {
    81.     cpplibtiny_call_func_table_rev (cpplibtiny_term_begin, cpplibtiny_term_end);
    82. }
    83.  
    84. void cpplibtiny_destroy_atexit_table()
    85. {
    86.     if (cpplibtiny_term_begin)
    87.         delete [] cpplibtiny_term_begin;
    88. }
    89.  
    90.  
    91. // //////////////////////////////////////////////
    92. // Utilities
    93.  
    94. void cpplibtiny_call_func_table (
    95.     cpplibtiny_funcptr * begin, cpplibtiny_funcptr * end)
    96. {
    97.     if (begin)
    98.         for (; begin < end; ++begin)
    99.             if (*begin)
    100.                 (*begin) ();
    101. }
    102.  
    103. void cpplibtiny_call_func_table_rev (
    104.     cpplibtiny_funcptr * begin, cpplibtiny_funcptr * end)
    105. {
    106.     if (begin)
    107.         for (--end; begin <= end; --end)
    108.             if (*end)
    109.                 (*end) ();
    110. }
    111.  
    112.  
    113. // //////////////////////////////////////////////
    114. // atexit
    115.  
    116. extern "C" int __cdecl atexit (void (__cdecl * func) () )
    117. {
    118.     // create atexit table if need
    119.     if (!cpplibtiny_term_begin)
    120.         cpplibtiny_term_begin = cpplibtiny_term_end =
    121.             (cpplibtiny_funcptr*) new cpplibtiny_funcptr [1000];
    122.     // push the function into the list
    123.     *cpplibtiny_term_end++ = func;
    124.     return 0;
    125. }
    126.  
    127.  
    128. // //////////////////////////////////////////////
    129. // Memory (de)allocation
    130.  
    131. void * operator new (unsigned size)
    132. {
    133.     return GlobalAlloc (0, size);
    134. }
    135.  
    136. void operator delete (void * ptr)
    137. {
    138.     GlobalFree (ptr);
    139. }
    140.  
    141.  
    142. // //////////////////////////////////////////////
    143. // Program entry point
    144.  
    145. //! Program entry point
    146. void cpplibtiny_main()
    147. {
    148.  
    149.     // do initializations
    150.     cpplibtiny_init();
    151.  
    152.     // execute user's code
    153.     extern int main();
    154.     int main_ret = main();
    155.  
    156.     // do deinitializations
    157.     cpplibtiny_deinit();
    158.  
    159.     ExitProcess (main_ret);
    160.  
    161. }
    P.S. Код мой, хотя и подозрительно похож на LIBCTINY ;)
     
  5. Rustem

    Rustem New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2004
    Сообщения:
    429
    Адрес:
    Russia
    Так как самому вызвать конструктор то?
     
  6. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Rustem
    За это отвечает компилятор и CRT. Тонкостей не знаю, но при определении статического объекта компилятор добавляет в специальную таблицу ссылку на вызов конструктора, а сами вызовы происходят при инициализации программы.
     
  7. Rustem

    Rustem New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2004
    Сообщения:
    429
    Адрес:
    Russia
    Так crt ведь сам написан на С. Значит можно вызвать?
     
  8. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Rustem
    Хм.. Под CRT я имел ввиду библиотеку поддержки С++. Она включает в себя поддержку как С, так и С++. Просто не знаю, как по-другому её назвать.
     
  9. maxdiver

    maxdiver Max

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    308
    Адрес:
    Саратов
    Rustem
    Добавь мой код в проект (можно отдельным файлом), и конструкторы и деструкторы глобальных объектов будут запускаться сами. (только нужно entry_point поменять на cpplibtiny_main).
    Подробности, на чём основан этот код, есть в MSDN - ищи по "LIBCTINY".
     
  10. maxdiver

    maxdiver Max

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    308
    Адрес:
    Саратов
    Очень вкратце можно так:
    если мы напишем
    Код (Text):
    1. #pragma data_seg(".CRT$XCA")
    2. static cpplibtiny_funcptr
    3.     cpplibtiny_init_begin[] = { 0 };
    4. #pragma data_seg(".CRT$XCZ")
    5. static cpplibtiny_funcptr
    6.     cpplibtiny_init_end[] = { 0 };
    7. #pragma data_seg()
    то массив cpplibtiny_init_begin будет содержать указатели на функции - конструкторы глобальных объектов. Размер этого массива определяется с помощью второго указателя cpplibtiny_init_end. Теперь достаточно просто пройтись по этому массиву и вызвать все функции из него (пропуская нулевые указатели). Имена переменным cpplibtiny_init_begin и cpplibtiny_init_end, естественно, можно давать любые, важно то, в какой секции они находятся. Первая переменная находится в секции .CRT и подсекции XCA, а вторая переменная - в подсекции XCZ. Где-то между ними (по-моему, в XCP) находится массив указателей на конструкторы - туда его кладёт компилятор. Фишка в том, что линкер сортирует подсекции по именам по алфавиту, т.е. массив указателей окажется обязательно между нашими указателями.
    Ну а с деструкторами всё аналогично.
     
  11. Rustem

    Rustem New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2004
    Сообщения:
    429
    Адрес:
    Russia
    Спасибо за ответы, буду разбираться