PDA

Просмотр полной версии : [Вопрос] Динамические параметры в функции для плагина SA-MP



KrutoyKrosch
27.10.2017, 18:19
Привет.

Толком не нашел нормальных мануалов по SAMP SDK для создания плагинов, только основы. Вроде все так понятно, но есть вещь до которой не могу догнать.

Как передавать в плагин динамическое кол-во аргументов? И как еще "возвращать массив"? Ну например как в sscanf.

sscanf(здесь массив в которую нужно вернуть строку из плагина, "", здесь динамическое кол-во аргументов);

И чтобы потом эти все "динамические аргументы" можно было передать например в функцию printf уже в плагине.

Не буду же я писать printf("%s%s%s%s%s%s", params[0], params[1], params[2] и т д);

Daniel_Cortez
27.10.2017, 19:04
Переместил тему в раздел по C/C++/C#.


Как передавать в плагин динамическое кол-во аргументов?
Точно так же, как и в обычную нативную функцию.


static cell AMX_NATIVE_CALL n_MemSort(AMX *amx, const cell *params)

В массиве params передаются все аргументы нативной функции. При этом 1-й аргумент находится в params[1], 2-й в params[2] и т.д., а params[0] содержит суммарный размер всех аргументов (в байтах). Разделите этот размер на размер одной ячейки (sizeof(cell)) - и получите количество аргументов для вашей функции.
Также в функциях с переменным числом аргументов все вариативные аргументы передаются по ссылке, т.е. передаётся не значение, а виртуальный адрес ячейки, в которой это значение находится. Из этого виртуального адреса с помощью функции amx_GetAddr() можно узнать физический адрес и по нему уже прочитать передаваемое значение.
Делается это примерно так:


cell amx_addr;
cell *phys_addr;
cell value;

amx_addr = params[3];
if (amx_GetAddr(amx, amx_addr, &phys_addr) != AMX_ERR_NONE)
{
// Неверный виртуальный адрес, здесь можно показать какое-нибудь сообщение об ошибке.
return 0;
}
value = *phys_addr;



И как еще "возвращать массив"? Ну например как в sscanf.
Массивы всегда передаются по ссылке, поэтому точно так же с помощью amx_GetAddr() узнаёте физический адрес и записываете по нему свои значения.


И чтобы потом эти все "динамические аргументы" можно было передать например в функцию printf уже в плагине.
Найдите нативную функцию и вызывайте её вручную. Поиск уже реализован здесь: https://github.com/maddinat0r/samp-plugin-sdk/blob/master/amxplugin2.cpp#L40

KrutoyKrosch
27.10.2017, 19:37
В последнем имел в виду вывод не в сам мод вызов функции printf. А в самом плагине, только там не printf, а logprintf вроде бы. Я же не знаю сколько аргументов было передано.

logprintf("", сюда нужно передать все аргументы которые поступили в static cell AMX_NATIVE_CALL n_MemSort(AMX *amx, const cell *params) );

Daniel_Cortez
28.10.2017, 11:41
В последнем имел в виду вывод не в сам мод вызов функции printf. А в самом плагине, только там не printf, а logprintf вроде бы. Я же не знаю сколько аргументов было передано.

logprintf("", сюда нужно передать все аргументы которые поступили в static cell AMX_NATIVE_CALL n_MemSort(AMX *amx, const cell *params) );

Такое возможно разве что на ассемблере (либо с помощью какой-нибудь специализированной библиотеки с ассемблерными вставками - я таких не видел, но что-то подобное наверняка уже успели изобрести, и не раз), но это явно уже перебор.
ИМХО, проще будет пройтись циклом по всем вариативным аргументам и вывести их через logprintf по одному.

ziggi
28.10.2017, 11:45
В последнем имел в виду вывод не в сам мод вызов функции printf. А в самом плагине, только там не printf, а logprintf вроде бы. Я же не знаю сколько аргументов было передано.

logprintf("", сюда нужно передать все аргументы которые поступили в static cell AMX_NATIVE_CALL n_MemSort(AMX *amx, const cell *params) );

https://stackoverflow.com/questions/1056411/how-to-pass-variable-number-of-arguments-to-printf-sprintf

Daniel_Cortez
28.10.2017, 11:56
https://stackoverflow.com/questions/1056411/how-to-pass-variable-number-of-arguments-to-printf-sprintf
Тоже хотел сначала предложить va_list, да только любая другая функция, кроме logprintf, не сохраняет текст в логе, а лишь выводит его в консоль.