14.06.2011, 06:47
(
Последний раз редактировалось Pghpunkid; 28.06.2011 в 04:11.
)
I went through a bit of problems when making a multi-parameter callback, so i thought id share the things i went through. So lets get started.
This isn't a from the ground up plugin example, If that is what you are looking for, click here.
So, in your plugin, you have your code, and now you want a callback to Pawn. (inb4 "Your doing it wrong.. etc etc etc")
Step 1: Setup
Now what i did to help organize these callbacks, is to make a separate function.
Plugin:
This will be our function within the plugin itself. With this callback, we want to send a string, and a number to our callback that we will call "OnSomethingHappens". The callback in pawn would look something like this:
Pawn:
The last step to setting this all up, is the function definition for the plugin (and for pawn if your not using an include.)
Plugin:
This goes outside of any function, above all of the functions. I place mine below my includes, and variables.
Pawn:
These are crucial to work.
There. The easy part is done. Now to make the plugin send the data to the callback.
Step 2: Plugin Function
When sending multiple variables to a callback using the amx_Push functions, you may not get things right the first time.. like i did. So lets look at how to do the plugin's function.
First you need to send the data from wherever in your plugin, to the function. We are going to be utilizing a string and number, both just put in somewhere for tutorial purposes, and not really useful practically.
So we call our plugin's function. Great! Now to send it to pawn.
Our Plugin function needs to push the integer and string to our callback "OnSomethingHappens" in Pawn. But before we can do that, we need to make sure we have something to send.
You should be checking each value, and if they are null or not. For example, checking if the length of your string is 0, by using strlen. if any of these variables are null or not given, then you should stop the function from sending bad data. Now if all checks are good, it returns 1, or a true boolean value (even though its an integer...)
Now for the amx stuff. Im not an expert at the amx address and all that, so as long as you use the right variable types in this next part, it should work just fine.
Okay so now our variables actually contain data, getting to the rest of the plugin's function. This is where, if you are following along with your own example, you would replace "OnSomethingHappens" with your own callback name. Also note, we moved return 1; inside the completed if statement. What this does is return 0 if there is a AMX Error, and 1 if there is no error, and it completes.
To make the plugin finally call your data, you utilize the amx_Push functions. There are 3 types (I believe); amx_Push, amx_PushString, and amx_PushArray. We will be using amx_Push, and amx_PushString.
One thing to keep in mind if you are using multiple parameters, is to push them in reverse order. This caused me several hours of needless debugging, and now im hoping to save you the same. So we call our string first, then the integer. Now, just to execute it.
If i am not mistaken, the variable ret is your return, however, your not expecting a return value from the Pawn call back, so NULL is a valid replacement, and you can go without the ret variable.
Step 3: Pawn, Compile and Test
Now go put a printf in your callback, compile it, and give it a shot. See what happens!
Hope this helps at least 1 person with their project!
This isn't a from the ground up plugin example, If that is what you are looking for, click here.
So, in your plugin, you have your code, and now you want a callback to Pawn. (inb4 "Your doing it wrong.. etc etc etc")
Step 1: Setup
Now what i did to help organize these callbacks, is to make a separate function.
Plugin:
Код:
int AnEventForCallingBack(int number,char string[]) { }
Pawn:
pawn Код:
public OnSomethingHappens(number1,string1[])
{
}
Plugin:
Код:
int AnEventForCallingBack(int number1, char string1[]);
Pawn:
pawn Код:
forward OnSomethingHappens(number1,string1[]);
There. The easy part is done. Now to make the plugin send the data to the callback.
Step 2: Plugin Function
When sending multiple variables to a callback using the amx_Push functions, you may not get things right the first time.. like i did. So lets look at how to do the plugin's function.
First you need to send the data from wherever in your plugin, to the function. We are going to be utilizing a string and number, both just put in somewhere for tutorial purposes, and not really useful practically.
Код:
Somewhere in the plugin: AnEventForCallingBack(5,"This is a string.");
Our Plugin function needs to push the integer and string to our callback "OnSomethingHappens" in Pawn. But before we can do that, we need to make sure we have something to send.
Код:
int AnEventForCallingBack(int number1,char string1[]) { if (strlen(string1) == 0) return 0; if (number1 == NULL) return 0; return 1; }
Now for the amx stuff. Im not an expert at the amx address and all that, so as long as you use the right variable types in this next part, it should work just fine.
Код:
int AnEventForCallingBack(int number1,char string1[]) { if (strlen(string1) == 0) return 0; if (number1 == NULL) return 0; int idx; cell ret, amx_Address,*phys_addr; int amxerr = amx_FindPublic(pAMX, "OnSomethingHappens", &idx); if (amxerr == AMX_ERR_NONE) { return 1; } return 0; }
To make the plugin finally call your data, you utilize the amx_Push functions. There are 3 types (I believe); amx_Push, amx_PushString, and amx_PushArray. We will be using amx_Push, and amx_PushString.
Код:
int AnEventForCallingBack(int number1,char string1[]) { if (strlen(string1) == 0) return 0; if (number1 == NULL) return 0; int idx; cell ret, amx_Address,*phys_addr; int amxerr = amx_FindPublic(pAMX, "OnSomethingHappens", &idx); if (amxerr == AMX_ERR_NONE) { amx_PushString(pAMX,&amx_Address,&phys_addr,string1,0,0); amx_Push(pAMX, number1); return 1; } return 0; }
Код:
int AnEventForCallingBack(int number1,char string1[]) { if (strlen(string1) == 0) return 0; if (number1 == NULL) return 0; int idx; cell ret, amx_Address,*phys_addr; int amxerr = amx_FindPublic(pAMX, "OnSomethingHappens", &idx); if (amxerr == AMX_ERR_NONE) { amx_PushString(pAMX,&amx_Address,&phys_addr,string1,0,0); amx_Push(pAMX, number1); amx_Exec(pAMX, &ret, idx); return 1; } return 0; }
Step 3: Pawn, Compile and Test
Now go put a printf in your callback, compile it, and give it a shot. See what happens!
Hope this helps at least 1 person with their project!