Лайфхак с функциями для Pawn AMX
Привет всем.
Не так давно в одном из своих личных проектов мне понадобилось сделать нативные функции для Pawn AMX.
Для примера возьмём одну из таких функций: она должна была принимать 2 аргумента (ID участка памяти, в котором нужно отсортировать значения, как в массиве, и порядок сортировки) и нужно было сделать проверку на то, что этих аргументов передано нужное количество (кто знает, может быть в скрипте неправильный заголовок функции с 1 или даже 0 параметрами вместо 2?)
Выглядел код примерно так:
PHP код:
static cell AMX_NATIVE_CALL n_MemSort(AMX *amx, const cell *params)
{
// CheckArgs проверяет кол-во аргументов и, если их меньше, чем нужно, поднимает ошибку.
if (!CheckArgs(2))
return 0;
// Если есть нужное кол-во аргументов - отсортировать значения в участке памяти.
return MemoryPool_Sort(amx, params[1], params[2]);
}
Меня этот результат не устроил сразу по нескольким причинам.
Во-первых, чтобы понять, что кроется в 1-м и 2-м аргументе, нужно открывать заголовочный файл на Pawn (*.inc).
Во-вторых, чем больше таких аргументов в функции, тем легче их перепутать.
В-третьих, последний параметр в CheckArgsNumber нужно подсчитывать вручную. ИЧСХ, с ним тоже легко ошибиться (например, указать 3 вместо 2), особенно из-за copy-paste.
Мне захотелось переложить работу по контролю аргументов функции на компилятор, поэтому я придумал небольшой трюк с перечислением ID аргументов в enum:
PHP код:
static cell AMX_NATIVE_CALL n_MemSort(AMX *amx, const cell *params)
{
enum
{
args_size,
arg_pointer_id,
arg_sort_type,
__dummy_elem_, num_args_expected = __dummy_elem_ - 1
};
if (!CheckArgs())
return 0;
return MemoryPool_Sort(amx, params[arg_pointer_id], params[arg_sort_type]);
}
С таким вариантом у каждого из параметров есть своё название, перепутать params[arg_pointer_id] и params[arg_sort_type] куда сложнее, чем params[1] и params[2], а в CheckArgsNumber не нужно самостоятельно считать количество параметров функции - оно само подсчитывается в args_expected_number.
P.S. Если кому-нибудь будет интересно, вот сама функция CheckArgs, вернее, макрос:
PHP код:
#define CheckArgs() pluginutils::CheckNumberOfArguments(amx, params, num_args_expected)
В нём, в свою очередь, используется функция pluginutils::CheckNumberOfArguments, которую можно найти в файлах pluginutils.h/.cpp из моего шаблона для плагинов:
Автор: Daniel_Cortez
Копирование данной статьи на других ресурсах без разрешения автора запрещено!