Рейтинг - 4.4 (7)

Всем привет! После 2-х месяцев застоя я продолжаю вести уроки по скриптингу. Сегодняшний урок будет посвящен DLL-библиотекам. Мы будем учится подключать, написанные нами, файлы.

Библиотека - это набор функций, написанных на любом языке программирования. В этом уроке мы напишем простейшую библиотеку на С++ и используем её в Cleo-скрипте. Этот урок будет приквел в написании ASI-скриптов.

Начнем с написания. Для примера, я взял Visual Studio 2008, с помощью которой мы создадим библиотеку. Для этого, откроем новый проект и укажем тип проекта:

Указываем шаблон "Консольное приложение Win32", тип проекта - "Win32". Вводим имя проекта и нажимает "ОК". После чего в нас появиться диалоговое окно такого типа:

Выбираем "DLL", и ставим галочку на пустой проект, после чего нажимаем кнопку "Готово". Программа создала нам 3 папки: "Заголовочные файлы", "Файлы исходного кода" и "Файлы ресурсов". Выбираем папку "Файлы исходного кода", нажимаем правую кнопку мыши и выбираем опцию "Добавить->Создать элемент":

В появившемся окне выбираем "Код->Файл CPP". В поле "Имя" мы даём название нашему исходному файлу:

Когда данные заполнены, нажимаем "Добавить". Перед нами пустой проект. Здесь мы будем писать код библиотеки. Все функции должны быть экспортными, поэтому перед каждой из них мы должны написать код:

extern "C" __declspec(dllexport)

Используя язык C++, мы напишем простенькую функцию, которая будет возвращать нам сумму 3-х целых чисел. Мой код такой:

int plus(int a, int b, int c){ 
 return a+b+c;
}

Всё, что остаётся - дописать код эксторта и подключить стандартную библитеку "iostream":

#include <iostream>

extern "C" __declspec(dllexport) int plus(int a, int b, int c){ 
 return a+b+c;
}

Теперь скомпилируем код, нажав на конку или клавишу F5. Если у нас всплывает окно с сообщением о том, что нужно указать исполняющий файл, то нажимаем "Отмена". От нас требуют запустить какую-то программу, что бы проверить работоспособность. В нашем случае нет нужды что-то указывать, по этому нажимает отрицательный вариант. Что бы не выскакивало это окно, то пользуемся клавишей F7.

Нам осталось скопировать нашу DLL в папку с игрой. Я, например, кину её в папку "Cleo":

Теперь берём в руки наш любимый Sanny Builder и будем писать код :) Для начала, рассмотрим опкоды, которые работают DLL-библиотекой. Следующий опкод загружает библиотеку в память

0AA2: 0@ = load_library "CLEO\wmysterio.dll" // IF and SET
Здесь:
0@ - имя загруженной библиотеки
"CLEO\wmysterio.dll" - путь с самой DLL-ке.
0AA3: free_library 0@

Опкод выгружает ранее загруженную библиотеку из памяти.

Здесь:
0@ - имя загруженной библиотеки

Получить адрес функции библиотеки можно с помощью опкода:

0AA4: 1@ = get_proc_address "plus" library 0@ // IF and SET
Здесь:
0@ - хэндл загруженной библиотеки
"plus" - имя фунции в библиотеке
1@ - в переменную заносится адрес функции
0AA7: call_function 1@ num_params 3 pop 3 _c=10 _b= 5 _a= 3 store_to 2@

Опкод выполняет функцию по адресу.

Здесь:
1@ - адрес функции
num_params 3 - количество параметров, передаваемых в функцию. Так, как наша библиотека принимает 3 параметра, то число будет тоже 3. Следует учесть, что это "плавающий" параметр и количество зависит от самих функций. Обратите внимание, передача параметров осуществляется в обратном порядке! pop 3 - количество параметров, которых нужно очистить после использования функции. Этот параметр обычно совпадает с к-вом передаваемых параметров.
_c=10 _b= 5 _a= 3 - перечисление параметров, которые будут переданы в функцию. К-во должно строго совпадать с к-вом параметров в нашей dll-ке. В нашем случаи мы передадим числа 10, 5 и 3.
2@ - переменная, в которую будет возвращено значение. В нашем случае эта переменная необходимая, но если функция ничего не возвращает, то поле остаётся пустым.

Следует обратить внимание, что этот опкод выполняет функции не только DLL-библиотек, но и GTA-шные функции. О них я расскажу в следующих уроках.

{$CLEO}
0000:

:MyDLL
thread 'MyDLL'
wait 5000
if
0AA2: 0@ = load_library "CLEO\wmysterio.dll" // IF and SET
jf @MyDLL_END_1
if
0AA4: 1@ = get_proc_address "plus" library 0@ // IF and SET
jf @MyDLL_END_2
$PARAM_1 = 3
$PARAM_2 = 5
0AA7: call_function 1@ num_params 3 pop 3 10 $PARAM_2 $PARAM_1 result_to $RES
0ACE: show_formatted_text_box "Summ: %d" $RES
0AA3: free_library 0@
jump @MyDLL_END

:MyDLL_END_1
wait 0
0ACE: show_formatted_text_box "FILE NOT FOUND"
jump @MyDLL_END

:MyDLL_END_2
wait 0
0ACE: show_formatted_text_box "ADDRESS NOT FOUND"

:MyDLL_END
wait 0
0A93: end_custom_thread

Проверяем наш скрипт:

Нам вывело число 18, то есть, наша функция работает без проблем!

Это самый простой пример, дальше я постепенно буду умерено усложнять библиотеки. Обычно их используют как для написания новых опкодов, так и целых ASI-скриптов, но их принцип написания существенно отличается. На этом урок окончен! Надеюсь эти навыки пригодятся Вам ;)


Теги: dll

KiLLeR96   (24.03.13 15:26)
Круто! Только если бы что-то по-сложней

wmysterio   (24.03.13 19:06)
Буду осложнять с каждым уроком. Главное, что бы понятно было biggrin

SanKing   (01.04.13 10:36)
Да уж, это посложнее, чем "просто скриптинг"!

CraZZZy-GameRRR   (05.07.13 01:21)
Ничего не понимаю! Делаю всё точно по инструкции, а скрипт функцию не находит, хотя к exe-шнику она подключается. Только у меня VS не 2008, а 2010. Может в этом причина?

wmysterio   (05.07.13 01:27)
Возможно у Вас в настройках компилятора Sanny builder регистр не выставлен в режим "как есть" во вкладке "Форматирование".

CraZZZy-GameRRR   (05.07.13 02:12)
Да, так оно и есть. Как это я сам не додумался?! Спасибо.

Yurko_UA   (11.07.13 22:03)
Хочется что-то посложнее..

Yurko_UA   (23.07.13 23:58)
Скоро будет про GTA'шние функции? А то руки чешутся.

wmysterio   (24.07.13 18:32)
Если и будет, то это будет не скоро sad

Vital   (24.07.13 17:46)
Здорово! Очень полезно, тем более, что позволяет делать ранее невозможные вещи, как я думаю. А графическое меню можно написать как dll (по типу CamHunt)?

BoPoH   (25.12.13 21:40)
Vital, вообще-то CamHunt использует плагин GUI, который я написал специально для CamHunt, но он может использоваться и другими плагинами/скриптами. Принцип тот же самый - экспорт функций. Этот плагин позволяет создавать различные элементы интерфейса (окна, кнопки, чекбоксы и т.п.). Возможно позже я доработаю его и выложу документацию к нему.

Кстати, насчёт туториала. Тут есть одна ошибка. Конечно, в данном примере она не влияет на результат. Я имею ввиду порядок передачи параметров в функцию. Если функция принимает 3 параметра a, b и c, то в опкоде 0AA7 их нужно писать в обратном порядке, т.е. c, b, a.

wmysterio   (26.12.13 05:15)
BoPoH, исправил.
Вход на сайт

Поиск
Категории раздела
Мини-чат
Пожалуйста, все вопросы по скриптингу задавать на форуме!
Наш опрос
А вы проходили GTA San Andreas на 100% без читов и скриптов?
Всего ответов: 6
Активность на сайте
Пожертвования
Кошельки WebMoney:
U859420971000
R407741810602
Z331072372430
E314272616890
Друзья сайта
Полезные ресурсы
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Сегодня нас посетили:
Рекомендую
Реклама