Алекс Jenter - Программирование на Visual C++. Архив рассылки

Тут можно читать онлайн Алекс Jenter - Программирование на Visual C++. Архив рассылки - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    Программирование на Visual C++. Архив рассылки
  • Автор:
  • Жанр:
  • Издательство:
    неизвестно
  • Год:
    неизвестен
  • ISBN:
    нет данных
  • Рейтинг:
    4.33/5. Голосов: 91
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

Алекс Jenter - Программирование на Visual C++. Архив рассылки краткое содержание

Программирование на Visual C++. Архив рассылки - описание и краткое содержание, автор Алекс Jenter, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

РАССЫЛКА ЯВЛЯЕТСЯ ЧАСТЬЮ ПРОЕКТА RSDN, НА САЙТЕ КОТОРОГО ВСЕГДА МОЖНО НАЙТИ ВСЮ НЕОБХОДИМУЮ РАЗРАБОТЧИКУ ИНФОРМАЦИЮ, СТАТЬИ, ФОРУМЫ, РЕСУРСЫ, ПОЛНЫЙ АРХИВ ПРЕДЫДУЩИХ ВЫПУСКОВ РАССЫЛКИ И МНОГОЕ ДРУГОЕ.

Программирование на Visual C++. Архив рассылки - читать онлайн бесплатно полную версию (весь текст целиком)

Программирование на Visual C++. Архив рассылки - читать книгу онлайн бесплатно, автор Алекс Jenter
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

В составе библиотеки ATL версии 3 и более ранних имеется файл atlimpl.cpp. Он, как правило, включается в один из исходных файлов проекта (чаще всего в stdafx.cpp) с помощью директивы #include. В atlimpl.cpp находится "облегченная" реализация стартового кода CRT: в нее входят только вариант функции xxx CRTStartup, упомянутой ранее, и "обертки" для работы с динамической памятью – функции malloc, calloc, realloc, free и операторы new/delete. Они непосредственно вызывают функции Windows для работы с кучей – HeapAllocи HeapFree. Как ни странно, этого достаточно, чтобы заставить заработать без CRT startup множество программ.

Собственно, сама эта реализация доступна, только если определен символ препроцессора _ATL_MIN_CRT. Таким образом, есть возможность легко управлять включением или исключением стартового кода CRT.

ПРИМЕЧАНИЕ

Важный момент при использовании макроса ATL_MIN_CRT: по-прежнему нельзя включать объявления глобальных переменных, классы которых имеют конструкторы или деструкторы, так как код, их вызывающий, содержится только в CRT.

Эта проблема решена в библиотеке ATL 7.0 (не удивляйтесь, как и многие другие приложения Microsoft, ATL перескочила с версии 3 на версию 7), поставляемой с компилятором MS VC++ 7.0. Тем же, кто пользуется прежними версиями компилятора, могу посоветовать воспользоваться отличной библиотекой Andrew Nosenko's ATL/AUX Library, в которой содержится код вызова конструкторов/деструкторов. Для этого необходимо включать в проект вместо atlimpl.cpp файл AuxCrt.cppиз комплекта библиотеки.

Кто виноват?

Теперь ясно, что причиной появления ошибки "unresolved external symbol _main" стало включение стартового кода CRT. То есть, была явно или неявно использована какая-либо функция, которая содержит ссылку на структуру данных, находящуюся в модуле с кодом инициализации. При включении компоновщиком в программу этого модуля возникает следующая внешняя ссылка: в теле mainCRTStartup есть вызов main. Вот и все, мы получили наше "любимое" сообщение об ошибке.

Отдельной "увлекательной" стадией сборки приложения является поиск функции или фрагмента кода, вызвавшего такую ситуацию. Для этого применяются следующие шаги:

• Включается опция компоновщика /verbose, при которой он выдает значительно большее количество диагностической информации.

• Включается опция компоновщика /nodefaultlib(или /nod), которая подавляет при сборке поиск библиотек, кроме указанных явно. При этом в списке неразрешенных внешних ссылок будут как "безобидные" функции CRT (которые можно будет включить явно), так и "тянущие" за собой стартовый код CRT.

• Локализовав модуль или функцию проекта, в которой появилась нежелательная внешняя ссылка на CRT, можно включить генерацию ассемблерного листинга (опция компилятора /FA) и простым поиском обнаружить, где происходит реальное включение.

Использование Standard Template Library

А как же насчет Standard Template Library (STL)? Насколько она завязана на CRT, можно ли использовать её в сверхмалых проектах?

Реализация STL от Dinkumware, поставляемая вместе с VC 5.0 и 6.0, доступна в исходных файлах, так что проблем с компоновкой не возникает. В крайнем случае, всегда можно исправить исходники или сделать какую-нибудь заглушку на #define'ах (перебивающую имена конструкций, тянущих за собой CRT). Другая проблема – в том, что STL повсеместно использует операторы динамического выделения памяти. Как уже говорилось, это вызывает необходимость собственной реализации операторов new/delete. Это можно сделать, например, так (идея позаимствована из atlimpl.cpp):

// stub.cpp – the "mini-CRT" implementation file

void* __cdecl malloc(size_t n) {

void* pv = HeapAlloc(GetProcessHeap(), 0, n);

return pv;

}

void* __cdecl calloc(size_t n, size_t s) {

return malloc(n*s);

}

void* __cdecl realloc(void* p, size_t n) {

if (p == NULL) return malloc(n);

return HeapReAlloc(GetProcessHeap(), 0, p, n);

}

void __cdecl free(void* p) {

if (p == NULL) return;

HeapFree(GetProcessHeap(), 0, p);

}

void* __cdecl operator new(size_t n) {

return malloc(n);

}

void __cdecl operator delete(void* p) {

free(p);

}

Вот пример программы, которая будет спокойно собрана с помощью такого подхода без стартового кода CRT:

#include

#include "stub.cpp"

#include

typedef std::map IntMap;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {

IntMap m;

for (int j=0; j<100; j++) m[j*j]=j;

IntMap::iterator i=m.find(49);

MessageBox(0, (i==m.end()) ? "49 was not found" : "49 was found", "std::map test", MB_OK);

return 0;

}

Для сборки этого примера необходимо использовать следующую командную строку:

cl test.cpp user32.lib kernel32.lib /link /nod /opt:nowin98 /subsystem:windows /entry:WinMain

Библиотека импорта kernel32.lib необходима для функций работы с Win32-кучей.

Что касается других реализаций STL, предоставлю слово Павлу Блудову:

Страшная тайна STL от SGI и HP в том, что им совершенно не нужна CRT.

С двумя оговорками:

1. Не используется C++ Exception Handling

2. (Вытекает из первой) определен макрос __THROW_BAD_ALLOC, например, так:

#ifndef _CPPUNWIND

#define __THROW_BAD_ALLOC \

::MessageBox(NULL, _T("STL: Out of memory."), NULL, MB_OK | MB_ICONSTOP); \

::ExitProcess(-5);

#endif _CPPUNWIND

#include

если посмотреть на __THROW_BAD_ALLOC, то он являет собой

#define __THROW_BAD_ALLOCfprintf(stderr, "out of memory\n"); exit(1)

именно эта строчка, и никакая другая, нуждается в CRT. Ну, если быть совсем точным, std::string'у может понадобиться CRT. Тут уж ничего не попишешь. Используйте WTL::CString.

Павел.

Слова о std::string в полной мере справедливы и для реализации STL от Dinkumware. Если вы ищете реализацию полноценного строкового класса, не использующего стартовый код CRT, советую взглянуть на CascStringв составе библиотеки ascLib.

Директива #import и ее ограничения в облегченных проектах

Частой причиной появления зависимости от CRT является необдуманное применение директивы #import– расширения visual c++ для удобства работы с COM-объектами, предоставляющими библиотеки типов. Подробнее о ней можно прочитать в MSDN, а на русском языке – в статье Игоря Ткачева "Использование директивы #import в Visual C++".

При ее использовании компилятор генерирует описания интерфейсов и, если не указано обратное, создает набор оберточных классов ( wrappers ) для упрощения работы с указателями на эти интерфейсы. Кроме того, детали реализации COM-объектов скрываются за высокоуровневыми средствами. В число таких деталей входят преобразование [out,retval]-параметров в возвращаемые значения функций, упрощение работы с BSTR-строками, управление сроками жизни объектов, доступ к свойствам и преобразование COM-HRESULT в исключения C++. Но поддержка всех этих приятных "мелочей" реализована с использованием CRT и требует включения стартового кода CRT.

Директива #import, несомненно, полезна для C++-программиста – ведь иначе, не имея описания интерфейсов, пришлось бы извлекать необходимую информацию вручную с помощью утилит типа OleView. Эту директиву можно применять и в проектах, не использующих CRT, но с рядом ограничений. В частности, необходимо подавить создание оберточных классов и трансляцию типов COM в классы-обертки _com_ptr, _com_error, _variant_t и _bstr_t. Вот пример выверенного использования #import, которое не "потянет" за собой половину кода CRT:

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Алекс Jenter читать все книги автора по порядку

Алекс Jenter - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Программирование на Visual C++. Архив рассылки отзывы


Отзывы читателей о книге Программирование на Visual C++. Архив рассылки, автор: Алекс Jenter. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x