I hadn't seen this before. This is incredible work - very well done!
|
This could do with more documentation on the rest of the amx_ functions. I came here the other day to look up some things and they weren't documented.
|
I'm not sure why you mention natives there at all.
Also, it would be helpful to explain a little more about "callbacks". We call PUBLIC functions "callbacks", the PAWN VM calls NATIVE functions "callbacks" and this can lead to some confusion if you don't remember that it's all point-of-view specific. The VM executes PAWN code and they some times "call back" in to the VM through natives. PAWN code executes functions, including natives, and these sometimes "call back" in to the PAWN script through publics. |
amx_Exec accesses an entry point (public function) in the script based off of the specified "index" parameter value. Any native function that the script uses will be sent to the amx_Callback function assuming that it wasnt overrided with amx_SetCallback. In this "callback" function any return value that is non-zero will result in the halting of execution of amx_Exec.
#include "SDK\amx\amx.h" #include "SDK\plugincommon.h" #include "Invoke.h" typedef void (*logprintf_t)(char* format, ...); logprintf_t logprintf; extern void *pAMXFunctions; cell AMX_NATIVE_CALL HelloWorld(AMX* amx, cell* params) { logprintf("This was printed from the Test plugin! Yay!"); return 1; } PLUGIN_EXPORT unsigned int PLUGIN_CALL Supports() { return SUPPORTS_VERSION | SUPPORTS_AMX_NATIVES; } PLUGIN_EXPORT bool PLUGIN_CALL Load(void **ppData) { invoke = new Invoke; pAMXFunctions = ppData[PLUGIN_DATA_AMX_EXPORTS]; logprintf = (logprintf_t) ppData[PLUGIN_DATA_LOGPRINTF]; logprintf(" * Test plugin was loaded."); return true; } PLUGIN_EXPORT void PLUGIN_CALL Unload() { logprintf(" * Test plugin was unloaded."); } AMX_NATIVE_INFO PluginNatives[] = { {"HelloWorld", HelloWorld}, {0, 0} }; PLUGIN_EXPORT int PLUGIN_CALL AmxLoad( AMX *amx ) { invoke->amx_list.push_back(amx); return amx_Register(amx, PluginNatives, -1); } PLUGIN_EXPORT int PLUGIN_CALL AmxUnload( AMX *amx ) { for (std::list<AMX *>::iterator i = invoke->amx_list.begin(); i != invoke->amx_list.end(); ++i) { if (* i == amx) { invoke->amx_list.erase(i); break; } } return AMX_ERR_NONE; }
What the hell... I'm just trying to use invoke and here is my results
![]() ![]() Code:
#include "SDK\amx\amx.h" #include "SDK\plugincommon.h" #include "Invoke.h" typedef void (*logprintf_t)(char* format, ...); logprintf_t logprintf; extern void *pAMXFunctions; cell AMX_NATIVE_CALL HelloWorld(AMX* amx, cell* params) { logprintf("This was printed from the Test plugin! Yay!"); return 1; } PLUGIN_EXPORT unsigned int PLUGIN_CALL Supports() { return SUPPORTS_VERSION | SUPPORTS_AMX_NATIVES; } PLUGIN_EXPORT bool PLUGIN_CALL Load(void **ppData) { invoke = new Invoke; pAMXFunctions = ppData[PLUGIN_DATA_AMX_EXPORTS]; logprintf = (logprintf_t) ppData[PLUGIN_DATA_LOGPRINTF]; logprintf(" * Test plugin was loaded."); return true; } PLUGIN_EXPORT void PLUGIN_CALL Unload() { logprintf(" * Test plugin was unloaded."); } AMX_NATIVE_INFO PluginNatives[] = { {"HelloWorld", HelloWorld}, {0, 0} }; PLUGIN_EXPORT int PLUGIN_CALL AmxLoad( AMX *amx ) { invoke->amx_list.push_back(amx); return amx_Register(amx, PluginNatives, -1); } PLUGIN_EXPORT int PLUGIN_CALL AmxUnload( AMX *amx ) { for (std::list<AMX *>::iterator i = invoke->amx_list.begin(); i != invoke->amx_list.end(); ++i) { if (* i == amx) { invoke->amx_list.erase(i); break; } } return AMX_ERR_NONE; } |
Hello, I'm trying to make something..
C++: Код:
int playerid = params[1]; int idx; if(!amx_FindPublic(amx,"__GetPlayerName",&idx)){ cell ret; cell* str_phys; cell amxaddr; amx_Push(amx,playerid); amx_Allot(amx,24,&amxaddr,&str_phys); amx_Push(amx,amxaddr); amx_Exec(amx,&ret,idx); char name[24]; amx_GetString(name,str_phys,0,24); amx_Release(amx,amxaddr); printf("%s",name); }else{ printf("Native"); } Код:
forward __GetPlayerName(playerid,name[]); public __GetPlayerName(playerid,name[]){ GetPlayerName(playerid,name,MAX_PLAYER_NAME); } P.S: I don't want to use invoke or gdk.I want to make this. P.S: playerid is correct.I tested. |
forward plugin_test( itg_MinX, itg_MinY, itg_MaxX, itg_MaxY );
public plugin_test( itg_MinX, itg_MinY, itg_MaxX, itg_MaxY )
{
printf( "comes from c++: %d, %d, %d, %d", itg_MinX, itg_MinY, itg_MaxX, itg_MaxY );
}
// calling: testfunc( amx, 5, 3, 2, 8 ); // function: void testfunc( AMX* amx, int itg_MinX, int itg_MinY, int itg_MaxX, int itg_MaxY ) { int idx; const cell arr[] = { itg_MinX, itg_MinY, itg_MaxX, itg_MaxY }; if(!amx_FindPublic(amx, "plugin_test", &idx)) { cell ret, addr = 0; cell amx_addr, *phys_addr; amx_Allot(amx, sizeof(arr) / sizeof(cell), &amx_addr, &phys_addr); memcpy(phys_addr, arr, sizeof(arr)); amx_Push(amx, amx_addr); amx_Exec(amx, &ret, idx); amx_Release(amx, addr); } }
@Rancho
use amx_PushString, you can get working examples in some of plugins(just look up some with callbacks that receive strings) @zgintasz You must amx_Push all values in reverse order(right-to-left), push theirs' amx addr of course. |
Failed (plugins/Plugin.so: undefined symbol: sampgdk_TextDrawShowForPlayer) |
#include <sampgdk/a_samp.h>
Hello, I'm trying to make something..
C++: Код:
int playerid = params[1]; int idx; if(!amx_FindPublic(amx,"__GetPlayerName",&idx)){ cell ret; cell* str_phys; cell amxaddr; amx_Push(amx,playerid); amx_Allot(amx,24,&amxaddr,&str_phys); amx_Push(amx,amxaddr); amx_Exec(amx,&ret,idx); char name[24]; amx_GetString(name,str_phys,0,24); amx_Release(amx,amxaddr); printf("%s",name); }else{ printf("Native"); } Код:
forward __GetPlayerName(playerid,name[]); public __GetPlayerName(playerid,name[]){ GetPlayerName(playerid,name,MAX_PLAYER_NAME); } P.S: I don't want to use invoke or gdk.I want to make this. P.S: playerid is correct.I tested. |