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

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

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

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/76954486.png)

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

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/68724190.png)

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

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/40297185.png)

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

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/58734607.png)

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

```
cpp
extern "C" __declspec(dllexport)
```

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

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

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

```
cpp
#include &#60;iostream>

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

Теперь скомпилируем код, нажав на конку ![](https://github.com/wmysterio/scm-scripting-lessons/blob/main/_pu/1/19665781.png) или клавишу F5`. Если у нас всплывает окно с сообщением о том, что нужно указать исполняющий файл, то нажимаем "Отмена". От нас требуют запустить какую-то программу, что бы проверить работоспособность. В нашем случае нет нужды что-то указывать, по этому нажимает отрицательный вариант. Что бы не выскакивало это окно, то пользуемся клавишей <kbd>F7`.

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

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/18035124.png)

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

```
0AA2: 0@ = load_library "CLEO&#92;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&#92;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
```

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

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/12473224.png)

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

Это самый простой пример, дальше я постепенно буду умерено усложнять библиотеки. Обычно их используют как для написания новых опкодов, так и целых ASI-скриптов, но их принцип написания существенно отличается. На этом урок окончен! Надеюсь эти навыки пригодятся Вам ;)|3226|1|0|76954486`png`794`531`400`267``\|68724190`png`756`428`400`226``\|40297185`png`483`234`400`193``|58734607`png`793`504`400`254``\|18035124`png`447`328`400`293``\|12473224`png`600`337`400`224``|19665781`png`23\`22

```
`\||napisanija_dll_bibliotek_i_ispolzovanie_ikh_s_skriptakh|1504461926
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lessons.sannybuilder.com/00100/00400/00097.-napisaniya-dll-bibliotek-i-ispolzovanie-ikh-s-skriptakh.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
