Уроки моддинга
Основной раздел
Search…
⌃K
Links

00097. Написания DLL библиотек и использование их с скриптах

Написания DLL библиотек и использование их с скриптах|Всем привет! После 2-х месяцев застоя я продолжаю вести уроки по скриптингу. Сегодняшний урок будет посвящен DLL-библиотекам. Мы будем учится подключать, написанные нами, файлы.|wmysterio|wmysterio||||Библиотека - это набор функций, написанных на любом языке программирования. В этом уроке мы напишем простейшую библиотеку на С++ и используем её в Cleo-скрипте. Этот урок будет приквел в написании ASI-скриптов.
Начнем с написания. Для примера, я взял Visual Studio 2008, с помощью которой мы создадим библиотеку. Для этого, откроем новый проект и укажем тип проекта:
Указываем шаблон "Консольное приложение Win32", тип проекта - "Win32". Вводим имя проекта и нажимает "ОК". После чего в нас появиться диалоговое окно такого типа:
Выбираем "DLL", и ставим галочку на пустой проект, после чего нажимаем кнопку "Готово". Программа создала нам 3 папки: "Заголовочные файлы", "Файлы исходного кода" и "Файлы ресурсов". Выбираем папку "Файлы исходного кода", нажимаем правую кнопку мыши и выбираем опцию "Добавить->Создать элемент":
В появившемся окне выбираем "Код->Файл CPP". В поле "Имя" мы даём название нашему исходному файлу:
Когда данные заполнены, нажимаем "Добавить". Перед нами пустой проект. Здесь мы будем писать код библиотеки. Все функции должны быть экспортными, поэтому перед каждой из них мы должны написать код:
cpp
extern "C" __declspec(dllexport)
Используя язык C++, мы напишем простенькую функцию, которая будет возвращать нам сумму 3-х целых чисел. Мой код такой:
cpp
int plus(int a, int b, int c){
return a+b+c;
}
Всё, что остаётся - дописать код эксторта и подключить стандартную библитеку "iostream":
cpp
#include <iostream>
extern "C" __declspec(dllexport) int plus(int a, int b, int c){
return a+b+c;
}
Теперь скомпилируем код, нажав на конку
или клавишу F5. Если у нас всплывает окно с сообщением о том, что нужно указать исполняющий файл, то нажимаем "Отмена". От нас требуют запустить какую-то программу, что бы проверить работоспособность. В нашем случае нет нужды что-то указывать, по этому нажимает отрицательный вариант. Что бы не выскакивало это окно, то пользуемся клавишей <kbd>F7.
Нам осталось скопировать нашу DLL в папку с игрой. Я, например, кину её в папку "Cleo":
Теперь берём в руки наш любимый Sanny Builder и будем писать код :) Для начала, рассмотрим опкоды, которые работают DLL-библиотекой. Следующий опкод загружает библиотеку в память
0AA2: [email protected] = load_library "CLEO&#92;wmysterio.dll" // IF and SET
Здесь: [email protected] - имя загруженной библиотеки "CLEO\wmysterio.dll" - путь с самой DLL-ке.
0AA3: free_library [email protected]
Опкод выгружает ранее загруженную библиотеку из памяти.
Здесь: [email protected] - имя загруженной библиотеки× **ВАЖНО:** Библиотеку нужно всегда выгружать из памяти после использования
Получить адрес функции библиотеки можно с помощью опкода:
0AA4: [email protected] = get_proc_address "plus" library [email protected] // IF and SET
Здесь: [email protected] - хэндл загруженной библиотеки "plus" - имя фунции в библиотеке [email protected] - в переменную заносится адрес функции
0AA7: call_function [email protected] num_params 3 pop 3 _c=10 _b= 5 _a= 3 store_to [email protected]
Опкод выполняет функцию по адресу.
Здесь: [email protected] - адрес функции num_params 3 - количество параметров, передаваемых в функцию. Так, как наша библиотека принимает 3 параметра, то число будет тоже 3. Следует учесть, что это "плавающий" параметр и количество зависит от самих функций. Обратите внимание, передача параметров осуществляется в обратном порядке! pop 3 - количество параметров, которых нужно очистить после использования функции. Этот параметр обычно совпадает с к-вом передаваемых параметров. _c=10 _b= 5 _a= 3 - перечисление параметров, которые будут переданы в функцию. К-во должно строго совпадать с к-вом параметров в нашей dll-ке. В нашем случаи мы передадим числа 10, 5 и 3. [email protected] - переменная, в которую будет возвращено значение. В нашем случае эта переменная необходимая, но если функция ничего не возвращает, то поле остаётся пустым.
Следует обратить внимание, что этот опкод выполняет функции не только DLL-библиотек, но и GTA-шные функции. О них я расскажу в следующих уроках.
{$CLEO}
0000:
:MyDLL
thread 'MyDLL'
wait 5000
if
0AA2: [email protected] = load_library "CLEO&#92;wmysterio.dll" // IF and SET
jf @MyDLL_END_1
if
0AA4: [email protected] = get_proc_address "plus" library [email protected] // IF and SET
jf @MyDLL_END_2
$PARAM_1 = 3
$PARAM_2 = 5
0AA7: call_function [email protected] num_params 3 pop 3 10 $PARAM_2 $PARAM_1 result_to $RES
0ACE: show_formatted_text_box "Summ: %d" $RES
0AA3: free_library [email protected]
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-скриптов, но их принцип написания существенно отличается. На этом урок окончен! Надеюсь эти навыки пригодятся Вам ;)|3226|1|0|76954486png794531400267``\|68724190png756428400226\|40297185`png`483`234`400`193|58734607png793504400254``\|18035124png447328400293\|12473224`png`600`337`400`224|19665781png23`22
`\||napisanija_dll_bibliotek_i_ispolzovanie_ikh_s_skriptakh|1504461926