Plugin development

Started by habi, Aug 07, 2020, 06:03 AM

Previous topic - Next topic

habi

I see that many players have difficulty in plugin development. One of the members asked me how to call a plugin function ( a c++ function inside the plugin) from squirrel.

First of all download a plugin template which has squirrel connected. One you can find in my older post https://forum.vc-mp.org/?topic=7743.0

You might be the first time using C++, never mind. It is so simple. Just google how to install this 'Visual Studio'.

Now when you open the project(.vcxproj), you can see many source files on your right side. Find SQFuncs.cpp. we are going to edit it.

If you open it, into the bottom you can find a function named 'RegisterFuncs'. I think it is created by the LU devs or someone.

Do you know what we are going to do. We are going to create a small function in c++, which can be called from our squirrel. Think of it. In squirrel, we load the plugin from server.cfg and call 'this function' from squirrel. How beautiful?

In some other tutorial i will show how to do the reverse, i.e calling a squirrel function from c++. by squirrel function i mean
function abcd(a,b)
{
     print ("a is "+a+ " and b is "+b);
}

It is easy to understand if i tell you we are going to embed this function into plugin.
Say a is a string ie. a "something" and b is an integer ( 100 or something )
We are building a c++ function.
Now search SQFuncs.cpp for 'void RegisterFuncs(HSQUIRRELVM v) '
Just above that function add the following piece of code.
_SQUIRRELDEF(SQ_abcd) {
SQInteger n = sq->gettop(v);
if (n == 3) {
const SQChar* a;
sq->getstring(v, 2, &a);
SQInteger b;
sq->getinteger(v, 3, &b);
printf("a is %s and b is %d", a, b);
return 1;
}
return 0;
}
//'void RegisterFuncs(HSQUIRRELVM v) ' begins below
void RegisterFuncs(HSQUIRRELVM v) {

Now let us understand what is what. Don't ask me about 'void RegisterFuncs(HSQUIRRELVM v) ', because it is already there. i mentioned it to specify the location of posting our code.

OKay,
_SQUIRRELDEF(SQ_abcd) {All Squirrel type functions in vcmp plugin begins like this. SQ_abcd is the function name. you can name it as abcd also. (instead of SQ_). No problem. we need the name later.
SQInteger n = sq->gettop(v);Here we are getting the number of arguments passed to our plugin. we will be calling abcd("something",100) from squirrel. However, one extra argument, which i think is called 'root table' also comes. so in our case the number of arguments is not 2, but 3.
we could have used int n instead of SQInteger n. because in c++, everything we do with int. But don't worry. we can use this n the same way as we use int n anywhere. So keep it as SQInteger n.
sq->gettop will return how many arguments are passed( it is called stack and how many members in stack ). In our case we settle it, THREE.
if (n == 3) {
const SQChar* a;
We are checking if n is actually three. If somebody called 'abcd("something",100,200)' then n is 4. also n can be 2 if 100 and 200 are avoided.
Now SQChar* a
You know, in c++ strings are handled like 'char* a' and 'const char*a="hello" ' etc. Since we are dealing with squirrel, here it is SQChar* a.
sq->getstring(v, 2, &a);Now get the string and store in our variable 'a'. 2 means the second argument.
first argument is root table, second argument is "something" and third is 100 if we follow the pattern i mentioned above.
SQInteger b;
sq->getinteger(v, 3, &b);
I think this is obvious. See here it is 3, because (our second parameter becomes the third parameter here).
What in the world is &b. It is just a symbol used to denote the 'address' of b. Just keep it, no change. it works.
printf("a is %s and b is %d", a, b);
return 1;
This is obvious. I think you know about the c++ printf function. it is like our format function in old pawn. (btw i am building a pawn plugin now). s denotes string. d denotes integer.
return 1. this 1 will be returned to squirrel.
ie.abcd("something",200) ==1 in squirrel
tail return 0;
}
In case the function failed, zero is returned.

Now one more step is there.

Go to void RegisterFuncs(HSQUIRRELVM v) {
Inside this function in the end, before function closing bracket add a line.
RegisterSquirrelFunc(v, SQ_abcd, "abcd", 0, 0);This will tell the plugin to make a function named function abcd whose details will be provided by SQ_abcd.
i.e. whenever squirrel calls function abcd, it will redirects to SQ_abcd.
SQ_abcd is what we defined and explained in length above.

Press Ctrl+Shift+B and building starts. Hopefully no error will come. You can see output
C:\Users\...\Desktop\...\x64\Release\myplugin.dllOpen the folder and you can find your dll. I think i had set all options in the (.vcxproj) file so it will be simple for you.
(Go to Build->Configuration Manager->Active Solution Platform. Select x64 for 64 bit or x86 for 32 bit)
So we finally compiled a dll ( plugin ) for windows. (compiling a linux plugin is little difficult, i had already made a topic on it)

Now what? open server.cfg and add name of your plugin there.
Then run vcmp server to test. If you have ysc's input plugin you can straight go to console and type abcd();
Console
abcd("something",100)
a is something and b is 100

or if you do not have ysc's input plugin,
function onScriptLoad()
{
    abcd()

done

SexAppeal

This tutorial has been very helpful, thank you very much friend!

X Dukinja

Will Visual Studio 2008 work?

habi

I am not sure if it works with VS 2008.

However, there is a chance that it might work as there are no features such as lambda expressions, auto keyword, or newer standard library components in the plugin header.

Try it.

X Dukinja

;D Thanks for telling me. I guess Visual Studio 2010 will definitely work.

X Dukinja


Mohamed Boubekri

Perfect, this tutorial will be very usefull !
| What now ? | Not yet ! |
Morrocan:- [ 🇲🇦 ].