- •Лекция 1. Введение.
- •Лекция 2-3. Основные понятия. Типы данных.
- •Основные типы данных
- •Лекция 4 Выражения. Классификация операторов
- •Операторы объявлений типов и переменных
- •Операторы вызова функций
- •Математические и логические операции. Условная операция. Математические операции для целочисленных и вещественных вычислений.
- •Математические операции только для целочисленных вычислений
- •Логические операции.
- •Условная операция.
- •Операторы управления.
- •Оператор ветвления.
- •Оператор выбора.
- •Лекция 5. Циклы
- •Цикл while
- •Цикл for
- •Операция "запятая"
- •Цикл с условием на выходе: do while
- •Какой цикл лучше?
- •Другие управляющие операторы: break, continue, goto.
- •Лекция 6. Структуры данных. Массивы. Объединения. Строковые литералы.
- •1. Объявление массива
- •2. Инициализация массивов
- •3. 1 Работа с массивами
- •3.2. Обработка массивов
- •3.3. Ввод/вывод массивов
- •Объединения в c
- •Лекция 7. Функции. Рекурсия. 1 часть.
- •Лекция 8. Функции. Рекурсия. 2 часть.
- •Лекция 9. Указатели.
- •Функции управление памятью
- •Лекция 10. Динамические структуры данных.
- •Лекция 11. Файлы
- •Лекция 13. Объектно-ориентированные модели. Составные части объектного подхода.
- •Лекция 14. Классы. Конструкторы и деструкторы.
- •Лекция 15. Простое наследование классов
- •Лекция 16. Перегрузка функций
- •Лекция 17. Перегрузка операторов
- •Лекция 18. Друзья
- •Лекция 19. Шаблоны. Стандартная библиотека шаблонов
- •Лекция 20. Исключительные ситуации
- •Лекция 3.2. Проектирование структуры приложения. Система меню
- •Лекция 3.3.1. Стандартные и дополнительные компоненты
- •Лекция 3.3.2. Компоненты страницы Win32. Системные компоненты.
- •Лекция 3.4. Проектирование структуры данных
- •Лекция 3.6. Компоненты ActiveX. Графические компоненты
- •3.6.1.Компоненты ActiveX.
- •3.6.2. Графические компоненты
- •Лекция 4.1. Основные понятия языка. Переменные, операции, выражения. Операторы
- •Класс Array
- •Массивы как коллекции
- •Сортировка и поиск. Статические методы класса Array
- •Лекция 4.3. Делегаты, события и потоки выполнения. Работа с файлами библиотеки, атрибуты, директивы
- •Описание делегатов
- •Использование делегатов
- •Паттерн "наблюдатель"
- •Операции
- •Передача делегатов в методы
- •События
- •Многопоточные приложения
- •Класс Thread
- •Асинхронные делегаты
- •Лекция 5.1. Методы конструирования сложных программных систем
- •Inline-ассемблер в Delphi
- •Лекция 5.2. Разработка динамических библиотек
- •Для начала - что это такое ?
- •Далее разберемся: какая может быть польза от dll
Асинхронные делегаты
Делегат можно вызвать на выполнение либо синхронно, как во всех приведенных ранее примерах, либо асинхронно с помощью методов BeginInvoke и EndInvoke.
При вызове делегата с помощью метода BeginInvoke среда выполнения создает для исполнения метода отдельный поток и возвращает управление оператору, следующему за вызовом. При этом в исходном потоке можно продолжать вычисления.
Если при вызове BeginInvoke был указан метод обратного вызова, этот метод вызывается после завершения потока. Метод обратного вызова также задается с помощью делегата, при этом используется стандартный делегат AsyncCallback. В методе обратного вызова для получения возвращаемого значения и выходных параметров применяется метод EndInvoke.
Если метод обратного вызова не был указан в параметрах метода BeginInvoke, метод EndInvoke можно использовать в потоке, инициировавшем запрос.
Лекция 5.1. Методы конструирования сложных программных систем
Под программированием на нескольких языках мы будем понимать разработку одной программы с использованием нескольких языков и взаимодействие программ, написанных на разных языках
В программах на Visual C++ и Delphi можно делать ассемблерные вставки. Это называется inline-ассемблером. Обычно inline-ассемблер используется в двух случаях:
Если нужно оптимизировать критичные по скорости и небольшие по объему участки программы. грамотно написанный ассемблерный код всегда быстрее кода, который генерируется компилятором c++ или delphi.
Нужен прямой доступ к памяти и портам. чаще всего используется в драйверах, так как из третьего кольца защиты с портами не очень-то поработаешь.
Поскольку информации об inline-ассемблерах в интернете довольно мало, мы остановимся на этом подробнее.
Inline-ассемблер в Visual C++
Ассемблерные вставки в исходниках Visual C++ оформляются с помощью блока __asm и выглядят примерно так:
// обычный код на C++
printf("Hello!\n");
// а тут ассемблерная вставка
__asm {
mov eax, 2
mov edx, 7
add eax, edx
}
// а потом снова обычный код на C++
printf("Bye!");
Или, что то же самое, так:
// ассемблерная вставка
__asm mov eax, 2
__asm mov edx, 7
__asm add eax, edx
А можно вообще в одну строчку:
// ассемблерная вставка
__asm mov eax, 2 __asm mov edx, 7 __asm add eax, edx
В inline-ассемблере Visual C++ можно использовать все инструкции вплоть до Pentium 4 и AMD Athlon. Поддерживается также MMX. Поддержки Itanium и x64 пока нет :(.
По синтаксису inline-ассемблер Visual C++ частично совпадает с MASM. Например, как и в MASM можно строить выражения с операндами и использовать offset с глобальными переменными (смотри листинг 1). Как и в MASM, можно использовать глобальные метки и принудительно определять короткие переходы (смотри листинг 2). Однако определить локальную метку с помощью @@ в inline-ассемблере Visual C++ не получится – замена lab: на @@lab: в предыдущем примере вызовет ошибку компиляции. Есть и другие отличия от MASM. Например, в inline-ассемблере Visual C++ нет никаких средств для объявления переменных, поэтому про привычные DB, DW, DD, DQ, DT, DF, DUP и THIS можно забыть. Зато можно использовать переменные, объявленные в программе на C++ (смотри листинг 3).
В inline-ассемблере также нельзя объявлять структуры — директивы STRUC, RECORD, WIDTH и MASK недопустимы. Вместо этого можно использовать структуры, объявленные в программе на C++ (смотри листинг 4). Кроме того, в inline-ассемблере можно использовать комментарии и HEX-числа в стиле C++.
В принципе, все отличия подробно описаны в MSDN 2006 (идет в комплекте с Visual Studio 2006).
Обычно в Visual C++ inline-ассемблер используется для написания функций. Как правило, функции, написанные на inline-ассемблере, объявляют с использованием директивы _stdcall. В этом случае параметры передаются в функцию на стеке в обратном порядке, а результат работы возвращается в eax.
Для примера рассмотрим функцию, которая находит длину ASCIIZ-строки:
int _stdcall get_str_length(char *inputstr)
{
// чаще всего функция целиком состоит из одной
// большой ассемблерной вставки
__asm{
; можно свободно обращаться к переменным,
; переданным в функцию
mov edi, inputstr
mov esi, edi
mov ecx, -1
xor al, al
cld
repne scasb
sub edi, esi
; результат работы функции следует
; возвращать в eax
mov eax, edi
dec eax
}
}
Использовать эту функцию можно так:
int main()
{
char str_1[]="Hello, world!";
int i;
i = get_str_length(str_1);
printf("String: %s\nLength: %d", str_1, i);
}
При написании кода на inline-ассемблере Visual C++ следует помнить некоторые моменты. Во-первых, значения регистров не передаются между ассемблерными вставками. Например, если в ассемблерной вставке ты установил eax в 1, то в следующей ассемблерной вставке eax не обязательно будет равно 1 (смотри листинг 5).
Во-вторых, нужно быть осторожным с регистрами и стеком. В середине ассемблерных вставок нельзя менять регистры ds, ss, sp, bp и флаги. Если эти регистры все-таки меняются, перед выходом из ассемблерной вставки их нужно обязательно восстановить. Что касается стека, то тут нужно соблюдать правило, которое гласит: если в ассемблерной вставке нечто ложится на стек, то в той же ассемблерной вставке это «нечто» должно со стека сниматься.
Рассмотрим, например, такой код:
#include <stdio.h>
// наша функция на ассемблере
void _stdcall Test()
{
__asm{
; кладем на стек eax
push eax
; перед тем как ассемблерная вставка кончится, нужно
; снять eax со стека (например, с помощью pop),
; но мы забыли это сделать ;)
}
}
int main()
{
// вызываем функцию... и любуемся сообщением об ошибке :)
Test();
}
И, наконец, если ты пишешь не драйвер, а обычное Win32-приложение, в ассемблерной вставке не должно быть привилегированных инструкций. Вот, пожалуй, и все про inline-ассемблер Visual C++. Тем, кто хочет узнать больше, советуем почитать MSDN 2006 – там есть вся необходимая информация.