Алекс Jenter - Программирование на Visual C++. Архив рассылки
- Название:Программирование на Visual C++. Архив рассылки
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Алекс Jenter - Программирование на Visual C++. Архив рассылки краткое содержание
РАССЫЛКА ЯВЛЯЕТСЯ ЧАСТЬЮ ПРОЕКТА RSDN, НА САЙТЕ КОТОРОГО ВСЕГДА МОЖНО НАЙТИ ВСЮ НЕОБХОДИМУЮ РАЗРАБОТЧИКУ ИНФОРМАЦИЮ, СТАТЬИ, ФОРУМЫ, РЕСУРСЫ, ПОЛНЫЙ АРХИВ ПРЕДЫДУЩИХ ВЫПУСКОВ РАССЫЛКИ И МНОГОЕ ДРУГОЕ.
Программирование на Visual C++. Архив рассылки - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
HKLM\System\CurrentControlSet\Control\Session Manager\Memory Management
параметрами NonPagedPoolQuota и NonPagedPoolSize. Их значение по умолчанию равно нулю, что отдает управление этими значениями в руки операционной системы.
То есть при современных объемах памяти крайне сложно выбрать все ресурсы ядра операционной системы, создавая большое количество потоков. Остаются только ресурсы процесса, о чем мы и поговорим подробнее.
Как известно, каждому процессу выделяется адресное пространство в четыре гигабайта, но под свои нужды процесс может употребить только первые два гигабайта. Собственно из этих двух гигабайт и выделяется память под стек для вновь создаваемого потока. Размер стека определяется двумя факторами – параметром /STACK линковщика и параметром dwStackSize функции CreateThread.
Размер стека, заданный параметром dwStackSize, не может быть меньше, чем указано в параметре /STACK линковщика и по умолчанию равен ему. Размер стека, используемый линковщиком по умолчанию равен одному мегабайту. Таким образом максимальное количество потоков, которые можно создать при всех параметрах заданных по умолчанию, равняется примерно 2035. По достижении этого предела функция CreateThread начинает возвращать ошибку ERROR_NOT_ENOUGH_MEMORY, что является истинной правдой – если умножить количество потоков на размер стека по умолчанию, то как раз получается примерно два гигабайта – размер адресного пространства отданный процессу на карманные расходы.
Обойти это ограничение можно указав меньший размер стека параметром /STACK линковщика или в Project Settings (Link/Output/Stack Allocations/Reserve) в Microsoft Visual C++. Размер стека указывается в байтах. Меняя это значение надо быть осторожным ввиду того, что стек используется не только для хранения адресов возврата функций и передачи параметров, но и для хранения локальных переменных. Однако это тема отдельного разговора.
"Живые объекты" предоставляют очень интересные возможности для построения сложных систем. И проведенные тесты дают нам возможность трезво и со значительной степенью точности оценить влияние этой технологии на производительность конечной программы. Потому что лично меня, как программиста, очень нервирует манипулирование категориями "быстро/медленно" или "будет тормозить/не будет тормозить" ;)
Отдельное спасибо хочется сказать Дэну Парновскому, который сделал ряд ценных замечаний в процессе разработки тестовой программы, без которых результаты измерений были бы некорректны.
Так же хочу поблагодарить Константина Князева, чьи комментарии помогли более четко сформулировать некоторые ключевые моменты заметки.
ВОПРОС-ОТВЕТ
Как предоставить пользователю выбор источника данных для создания ADO Connection?
Автор: Марк Балонкин
Для определения источника данных во время выполнения существует DataLinkдиалог. Создать или отредактировать ADO Connectionс помощью DataLinkпоможет IDataSourceLocator(ole db). Пример кода:
// DataLocator.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#import "C:\Program Files\Common Files\System\ado\msado21.tlb" \
rename("EOF","ADOEOF") rename("BOF","ADOBOF")
#import "C:\Program Files\Common Files\System\ole db\Oledb32.dll"
int main(int argc, char* argv[]) {
CoInitialize(NULL);
MSDASC::IDataSourceLocatorPtr dl=NULL;
ADODB::_ConnectionPtr pConn=NULL;
try {
dl.CreateInstance(__uuidof(MSDASC::DataLinks));
pConn=dl->PromptNew();
if (NULL==pConn) return -1;
pConn->Open(pConn->ConnectionString, L"", L"", -1 );
} catch (_com_error&) {
return –1;
}
CoUninitialize();
return 0;
}
Это все на сегодня. Пока!
Алекс Jenter jenter@rsdn.ru Duisburg, 2001. Публикуемые в рассылке материалы принадлежат сайту RSDN.Программирование на Visual C++
Выпуск №65 от 24 февраля 2002 г.
Здравствуйте, дорогие подписчики!
СТАТЬЯ
Взаимодействие .NET с неуправляемым кодом
Автор: Алифанов Андрей
Демонстрационный проект
Первоначально цель написания данной статьи заключалась в следующем: показать, как писать обертки для низкоуровневых интерфейсов на языках семейства VisualStudio 7.0. Но по мере знакомства с предметом я понял, что тему можно расширить, так как схожие механизмы используются не только для взаимодействия с COM-объектами, но и для взаимодействия с низкоуровневым системным кодом Windows, в частности – с Win32 API. Кроме того, я думаю, что многим будет интересно узнать, как же в действительности выглядит код, который создается утилитами типа TlbImp(я здесь имею в виду код на языке C#, а не реально создающийся код на MSIL).
Эта тема достаточно актуальна для переходного периода, когда существует огромное количество кода, написанного с использованием Win32 API и COM-объектов, с которым нужно взаимодействовать. Проблема несколько смягчается, если используются объекты, описанные в библиотеках типов, за счет использования утилит, автоматически генерирующих сборки. Но что делать, если библиотеки типов нет или код находится в экспортируемой функции некоторой динамической библиотеки? В этом случае выход только один – вручную написать необходимые обертки.
Механизм, используемый для взаимодействия .NET с неуправляемым кодом, достаточно хорошо должен быть знаком тем, кто описывал интерфейсы на языке IDL. В обоих случаях используются атрибуты.
Атрибуты главным образом используются для правильного обмена данными между управляемым (managed) и неуправляемым (unmanaged) кодом, но не только.
Рассмотрение интеграции управляемого и неуправляемого кода начнем с PlatformInvoke. Эта технология позволяет достаточно просто вызывать функции динамических библиотек путем отображения объявления статического метода на точку входа PE/COFF.
Чтобы указать, что метод определен во внешней DLL, нужно пометить его как extern и использовать атрибут метода System.Runtime.InteropServices.DllImport. Этот атрибут сообщает CLR, что описание метода и дополнительные параметры (если они есть) необходимо использовать как информацию для вызова LoadLibrary и GetProcAddress, перед тем, как вызвать метод.
Атрибут DllImport имеет ряд параметров, которые можно опустить, но имя файла должно быть задано всегда. Это имя используется CLR для вызова LoadLibrary. Имя функции, которую необходимо вызвать из DLL, задается или прямым заданием параметра EntryPoint атрибута DllImport, или берется из описания самой функции. Во втором случае подразумевается, что ее название в программе соответствует ее имени в библиотеке. Пример использования этого атрибута приведен ниже:
[DllImport("KERNEL32.DLL", EntryPoint="MoveFileW", SetLastError=true, CharSet=CharSet.Unicode, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
public static extern bool MoveFile(String src, String dst);
Это все, что касается только технологии PlatformInvoke. Темы, рассматриваемые дальше, имеют отношение как к PlatformInvoke, так и к общению с COM-объектами из .NET. За исключением, естественно, описаний интерфейсов и классов.
Читать дальшеИнтервал:
Закладка: