20.03.2013, 17:12
(
Последний раз редактировалось xeeZ; 07.10.2013 в 08:59.
Причина: + sizeof(cell)
)
Calling other plugins' natives is a bit complex: you have to have an AMX instance on which you call the native function and do all the argument conversion (pushing and popping them on to the stack) similar to public functions.
You can use sampgdk_get_natives() and sampgdk_num_natives() to get the address of the native function you want to call. The former returns a pointer to the array of *all* native functions that have been registered (including those provided by plugins), not just the ones that are used by the AMX - so it's basically unimportant which AMX you'll pass in. The latter returns the number of entries in the array.
For example, to call SendClientMessage() you'd do something like this:
Note that some plugins like MySQL are built on top of third-party C or C++ libraries which you can use instead (and they are likely to be more flexible).
You can use sampgdk_get_natives() and sampgdk_num_natives() to get the address of the native function you want to call. The former returns a pointer to the array of *all* native functions that have been registered (including those provided by plugins), not just the ones that are used by the AMX - so it's basically unimportant which AMX you'll pass in. The latter returns the number of entries in the array.
For example, to call SendClientMessage() you'd do something like this:
pawn Код:
AMX_NATIVE FindNative(const char *name) {
const AMX_NATIVE_INFO *natives = sampgdk_get_natives();
int num_natives = sampgdk_num_natives();
for (int i = 0; i < num_natives; i++) {
if (strcmp(natives[i].name, name) == 0) {
return natives[i].func;
}
}
return 0;
}
bool DoSendClientMessage(int playerid, int color, const char *message) {
// Make this variable static to search for SendClientMessage only once.
static AMX_NATIVE native = FindNative("SendClientMessage");
// Push the arguments on to the stack. Here "amx" is some variable that
// holds a pointer to some AMX instance.
cell message_addr;
amx_PushString(amx, &message_addr, 0, message, false, false);
amx_Push(amx, color);
amx_Push(amx, playerid);
amx_Push(amx, 3 * sizeof(cell)); // 3 is the number of arguments
// All the "push" functions increase the parameter count which is later
// used (and reset) by amx_Exec(). But we don't use amx_Exec() so it has to
// be reset manually.
amx->paramcount = 0;
// Get the "params" pointer which points to our newly pushed arguments.
cell *params;
amx_GetAddr(amx, amx->stk, ¶ms);
// Call the function and pop the arguments off the stack.
cell retval = native(amx, params);
amx->stk += params[0] + sizeof(cell);
// Release all the string arguments as you would do with publics.
amx_Release(amx, message_addr);
return retval;
}