Добрый вечер, профи, и не только)
Меня интересует такой вопрос: возможно ли вызвать нативную функцию a_samp из плагина не прибегая к помощи Invoke?
Вид для печати
Добрый вечер, профи, и не только)
Меня интересует такой вопрос: возможно ли вызвать нативную функцию a_samp из плагина не прибегая к помощи Invoke?
sampgdk или вызывать функцию по адресу.
Я бы советовал сделать встроенную функцию написанную внутри инклуда твоего,
чтобы стандартные функции вызывались только на сервере,
а потом уже какая инфа от них нужна передавать в плагин.
По адресу через amx_FindNative? А так будет работать?
Так немного не получится, потому что нужно при вызове отправлять одни данные, которые находятся в инклуде, и сверять их с данными, которые только в плагине.
Да и в Invoke я что-то не нашёл нужного натива
Если вам нужно вызвать нативную функцию без использования сторонних библиотек (gInvoke или SAMPGDK), можете попробовать вызвать её через функцию-посредника на Pawn (т.е. с помощью amx_Exec() вызвать в скрипте public-функцию, которая уже вызовет нужный вам натив) или же в таблице нативных функций скрипта найти нужный натив и вызвать напрямую по адресу (но тогда обязательно нужно, чтобы нативная функция использовалась где-нибудь в скрипте, чтобы она была в таблице нативок; для этого можно просто создать в скрипте пустую public-функцию, которая нигде не используется и вызывает нативную функцию с любыми аргументами).
Второй способ сложнее в реализации, но лучше в плане производительности. Сложность заключается в том, что при вызове AMXLoad ещё нельзя узнать адрес натива, т.к. скрипт загружен, но ещё не инициализирован. Единственный способ - создать в плагине ещё одну нативную функцию, которая будет вызываться скриптом из OnGameModeInit/OnFilterScriptInit (сделать перехват в инклуде), и при вызове этой вспомагательной функции уже из неё узнавать адрес нужной вам нативки.
Но плагин вызывает поиск адреса натива при определённом действии, когда всё уже загружено и, по идее, инициализировано..
И такой вопрос: макрос (к примеру, MAX_PLAYERS) можно перенести в плагин?
Воспользуйтесь этой модифицированной версией SDK, в ней добавлено несколько доп. функций и макросов (см. файл amx2.h). В частности, вам понадобится макрос GETENTRY.
Код должен получиться примерно такой:
PHP код:
int func_index;
if (amx_FindNative(amx, "<имя натива>", &func_index) != AMX_ERR_NONE)
{
// Ошибка: нативная функция не найдена.
}
AMX_HEADER *hdr = (AMX_HEADER *)amx->base;
AMX_FUNCSTUB *func_stub = GETENTRY(hdr, natives, func_index);
AMX_NATIVE func = func_stub->func;
Почему бы и нет? Просто передавайте эту константу из скрипта в качестве параметра нативной функции в вашем плагине. Или можете вызвать GetPlayerPoolSize непосредственно из плагина.
Слегка отредачил пост выше (UPD)
Но вот касаемо второго: мне нужно создать глобальный массив в самом плагине, думаю, это не подойдёт в качестве параметра функции)
Я же говорю: мне нужно объявить глобальный массив int Array[MAX_PLAYERS];
что бы он хранил в себе число для каждого игрока, и по нему сверять данные сугубо в плагине
А из плагина вызывать функцию IsPlayerInRangeOfPoint. Но это я уже решил вызовом функции-посредника)
Ну да, как-то не подумал о динамике..
Спасибо за совет :smile:
Даниель, а Вы могли бы мне помочь в ЛС, или скайп, потому что у самого у меня справиться не получается, а здесь невероятно долго?..
Возникла одна проблема, похоже, из-за движка SAMP, либо я что-то неправильно понимаю, такое даже объяснить будет сложно
К сожалению, моих знаний недостаточно, что бы разобраться в таком вопросе, но Ваших, я почти уверен, вполне хватит, что бы объяснить мне за пять минут что к чему) Что почти не займёт ни Вашего, ни моего времени
Как известно, на русском языке нет никаких подробных туториалов к плагинописанию, а по иностранным разбираться довольно тяжко, поэтому единственным верным решением было бы обратиться именно к Вам.. Если и Вы бы не помогли, то мне оставалось бы идти только на samp.com
Поэтому, моя последняя надежда перед этим - только пообщаться с Вами)
Ведь моё свободное время тоже почти всё, как у Вас, уходит на кодинг..
Если так хотите, без проблем. Расскажите, какое значение возвращает amx_Exec в retval?
Я не писал плагины под SA-MP, но самый полезный навык программиста - уметь пользоваться поисковыми системами.
https://upload.teknik.io/S5Ltf.png
C моим уровнем английского: "Возвращает значение вызываемой функции или NULL, если функция не нуждается в возвращаемом значении".
Так вот дело в том, что это я давно знаю, НО
Как Вы объясните постоянный возврат единицы при любом исходе кода, но натив сам по себе не выполняет своё прямое действие?
А код показать? Без кода трудно, что либо сказать. Залей на gist/pastbin
P.S: вк - https://vk.com/id123663731, telegram: @continue98
Вот код конкретной функции, которая работает неправильно.
Думаю, здесь есть какие-то особенности для выполнения
Ну так правильно, не?
https://upload.teknik.io/A2BYn.pngPHP код:
main()
{
new pickup_armour = CreatePickup ( 1242, 2, 1503.3359, 1432.3585, 10.1191 );
new ret = DestroyPickup(pickup_armour);
printf("%d", ret);
}
Так дестрой вызывается по адресу из плагина. Смысл от этого кода?
Пикап не удаляется, а в плагин возвращается 1. В моде-то всё работает нормально
Да это всё было примерно одним вопросом, но к Даниелю.. Он должен разбираться в таких делах, а я даже не знаю что искать...
Просто это даже не первая функция, которая возвращает 1, а сама не выполняется
Привет. Например я хотел бы использовать самповскую родную функцию GetPlayerMoney в плагине. Не хотелось бы использовать GDK и др.
Как это пытаюсь сделать:
// C++ int __GetPlayerMoney(int playerid, AMX *amx) { int amx_index; cell amx_retval = 0; if (!amx_FindNative(amx, "GetPlayerMoney", &amx_index)) { amx_Push(amx, playerid); amx_Exec(amx, &amx_retval, amx_index); } return (int)amx_retval; } // native PLUGIN_GetPlayerMoney(playerid); static cell AMX_NATIVE_CALL n_PLUGIN_GetPlayerMoney(AMX *amx, cell *params) { return __GetPlayerMoney(params[1], amx); } AMX_NATIVE_INFO NATIVES_LIST[] = { {"PLUGIN_GetPlayerMoney", n_PLUGIN_GetPlayerMoney}, { 0, 0 } };
// Pawn native PLUGIN_GetPlayerMoney(playerid); { new money = PLUGIN_GetPlayerMoney(playerid); return 1; } forward CallGetPlayerMoney(); public CallGetPlayerMoney() { }
В итоге в printf'е money = 1. А по задумке ф-ия должна вернуть текущие деньги игрока.
Что я делаю не так?