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;
}

Нам осталось скопировать нашу 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-скриптов, но их принцип написания существенно отличается. На этом урок окончен! Надеюсь эти навыки пригодятся Вам ;)|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

Last updated