Чтение онлайн

на главную - закладки

Жанры

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

Jenter Алекс

Шрифт:

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

• Включается опция компоновщика /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 <windows.h>

#include "stub.cpp"

#include <map>

typedef std::map<int, int> 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 <stl_config.h>

если посмотреть на __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:

Поделиться:
Популярные книги

Газлайтер. Том 8

Володин Григорий
8. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 8

На Ларэде

Кронос Александр
3. Лэрн
Фантастика:
фэнтези
героическая фантастика
стимпанк
5.00
рейтинг книги
На Ларэде

Охота на попаданку. Бракованная жена

Герр Ольга
Любовные романы:
любовно-фантастические романы
5.60
рейтинг книги
Охота на попаданку. Бракованная жена

Кай из рода красных драконов

Бэд Кристиан
1. Красная кость
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Кай из рода красных драконов

Хозяйка Проклятой Пустоши. Книга 2

Белецкая Наталья
2. Хозяйка Проклятой Пустоши
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Хозяйка Проклятой Пустоши. Книга 2

Безумный Макс. Поручик Империи

Ланцов Михаил Алексеевич
1. Безумный Макс
Фантастика:
героическая фантастика
альтернативная история
7.64
рейтинг книги
Безумный Макс. Поручик Империи

Потусторонний. Книга 2

Погуляй Юрий Александрович
2. Господин Артемьев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Потусторонний. Книга 2

Чапаев и пустота

Пелевин Виктор Олегович
Проза:
современная проза
8.39
рейтинг книги
Чапаев и пустота

Солнечный корт

Сакавич Нора
4. Все ради игры
Фантастика:
зарубежная фантастика
5.00
рейтинг книги
Солнечный корт

Лютая

Шёпот Светлана Богдановна
Любовные романы:
любовно-фантастические романы
6.40
рейтинг книги
Лютая

Ведьмак (большой сборник)

Сапковский Анджей
Ведьмак
Фантастика:
фэнтези
9.29
рейтинг книги
Ведьмак (большой сборник)

Наследие Маозари 4

Панежин Евгений
4. Наследие Маозари
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Наследие Маозари 4

Ученик

Губарев Алексей
1. Тай Фун
Фантастика:
фэнтези
5.00
рейтинг книги
Ученик

Начальник милиции. Книга 5

Дамиров Рафаэль
5. Начальник милиции
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Начальник милиции. Книга 5