11.04.2010, 13:22
Мой первый плагин
Знаю, что подобные поделки уже существуют, но все же....
Данный плуг предназначен для управления (выделения/копирования/освобождения) динамической памятью напрямую через скрипты. Это удобно, например, если вы имеете дело с очень большими объемами данных, но не можете/не хотите иметь при этом *.amx чудовищно огромных размеров.
Выглядит это слегка коряво, по сравнению, скажем, с Cи (все данные, помещаемые в динамический "буфер", нельзя подать напрямую какой-нибудь стандартной функции, нужно сначала извлечь их во временный массив; указателей и подавно нет). Однако более удобной/гибкой реализации мне в голову, к сожалению, пока не пришло... так что если у вас есть предложения по улучшению/ усовершенствованию плагина - пишите!
Функции
Есть всего семь функций. Каждая оперирует с переменным типа Pointer: (указатель), которые на самом деле являются адресами выделенных участков памяти. Хотя звучит все просто, на самом деле не любой указатель можно передать в качестве аргумента (в целях безопасности), а лишь указывающий на один из выделенных блоков. Все они хранятся в специальной структуре (АВЛ-дерево), поиск по которой происходит довольно быстро, так что данные меры не сильно влияют на производительность.
Скачать
Как скомпилировать
Список изменений
Знаю, что подобные поделки уже существуют, но все же....
Данный плуг предназначен для управления (выделения/копирования/освобождения) динамической памятью напрямую через скрипты. Это удобно, например, если вы имеете дело с очень большими объемами данных, но не можете/не хотите иметь при этом *.amx чудовищно огромных размеров.
Выглядит это слегка коряво, по сравнению, скажем, с Cи (все данные, помещаемые в динамический "буфер", нельзя подать напрямую какой-нибудь стандартной функции, нужно сначала извлечь их во временный массив; указателей и подавно нет). Однако более удобной/гибкой реализации мне в голову, к сожалению, пока не пришло... так что если у вас есть предложения по улучшению/ усовершенствованию плагина - пишите!
Функции
Есть всего семь функций. Каждая оперирует с переменным типа Pointer: (указатель), которые на самом деле являются адресами выделенных участков памяти. Хотя звучит все просто, на самом деле не любой указатель можно передать в качестве аргумента (в целях безопасности), а лишь указывающий на один из выделенных блоков. Все они хранятся в специальной структуре (АВЛ-дерево), поиск по которой происходит довольно быстро, так что данные меры не сильно влияют на производительность.
pawn Код:
/* Выделяет участок динамической памяти определенного размера.
*
* Параметры:
* size - рамер блока (в ячейках, не в байтах)
* clear - если true, каждая ячейка выделенного участка будет заполнена указанным значенем.
* value - значение, которым необходимо заполнить все ячейки.
*
* Возвращает:
* Указатель на выделенный блок или NULL в случае ошибки (например, не хватило памяти).
*/
native Pointer:mem_allocate(size, bool:clear = false, value = 0);
/* Изменяет размер выделенного участка памяти.
*
* Параметры:
* ptr - указатель.
* new_size - новый размер.
*
* Возвращает:
* true при отсутствии ошибок, иначе - false.
*/
native bool:mem_resize(Pointer:ptr, new_size);
/* Освобождает память.
*
* Параметры:
* ptr - указатель на освобождаемый блок.
*
* Возвращает:
* true при отсутствии ошибок, иначе - false.
*
* Замечание: после вызова данной функции значение ptr недействительно
* и не может быть больше использовано, т.к. указывает на
* несуществующий блок.
*/
native bool:mem_free(Pointer:ptr);
/* Копирует содержимое блока в указанный массив.
*
* Параметры:
* source - указатель на копируемый.
* dest - буфер, в который производится копиррование.
* start - индекс первой копируемой ячейки (ее номер в блоке).
* count - количество копируемых ячеек.
*
* Возвращает:
* Число копированных элементов.
*/
native mem_get(Pointer:source, dest[], start = 0, count = sizeof(dest));
/* Копирует содержимое массива в указанный блок.
*
* Параметры:
* dest - указатель на блок, в который записывается массив.
* source - массив, элементы которого копировать.
* start - индекс первой копируемой ячейки (ее номер в блоке).
* count - количество копируемых ячеек.
*
* Возвращает:
* Число копированных элементов.
*/
native mem_set(Pointer:dest, const source[], start = 0, count = sizeof(source));
/* Копирует содержимое одного блока в другой.
*
* Параметры:
* source - указатель на копируемый блок.
* dest - указатель на второй блок, в который будет производена запись.
*
* Возвращает:
* Число копированных элементов.
*/
native mem_copy(Pointer:source, Pointer:dest);
/* Узнает размер ранее выделенного участка.
*
* Параметры:
* ptr - указатель на блок.
*
* Возвращает:
* Размер блока.
*/
native mem_size(Pointer:ptr);
Скачать
Как скомпилировать
- Linux
Перейдите в корень папки с проектом и наберите в терминале make
- Windows
- Visual Studio
Просто откройте проект и скомпилируйте, .dll появится в папке Release. Проект был создан в VS2010 Express, может не работать на старых версиях (не проверено).
- MinGW
Запустите командную оболочку Windows (Пуск -> Выполнить -> cmd), перейдите в папку проекта и выполните mingw32-make -f Makefile.mingw
- Visual Studio
Список изменений
pawn Код:
[13/04/2010]: v1.2.1
- Добавлена функция mem_size
[12/04/2010]: v1.2
- Изменены параметры некоторых функций
- Исправлены ошибки в процедурах mem_get/set/copy
- В инклуд добавлен удобный макрос, позволяющий выделять память прямо при объявлении указателя, без явного вызова mem_allocate
[11/04/2010]: v1.1
- Исправлен баг в mem_allocate, привыодивший к ошибке "out of memory"
- Исправлено падение сервера при вызове mem_free для некорректного адреса
- Исправлены мелкие недоработки при выводе сообщений об ошибках
[11/04/2010]: v1.0
- Первая версия