Show Changes Show Changes
Edit Edit
Print Print
Recent Changes Recent Changes
Subscriptions Subscriptions
Lost and Found Lost and Found
Find References Find References
Rename Rename
Administration Page Administration Page
Topic Locks Topic Locks

Search

History

3/17/2017 9:25:05 AM
-85.76.7.116
11/21/2016 1:36:53 PM
-207.244.89.107
12/26/2014 5:14:52 PM
-84.163.31.193
7/5/2014 5:12:14 AM
-88.181.126.101
3/2/2014 4:46:53 PM
-24.225.231.24
List all versions List all versions

RSS feed for the SquirrelWiki namespace

Embedding Getting Started
.

NEEDS MORE BETTER DOCUMENTATION

Check out the formatting tips on the right for help formatting and making links.

Use the template below:

Summary

This tutorial explains step by step how to build a minimal application that embed squirrel, load and run a script.

First let's take a look at the following script and C code, later I'll be explaing in detail what they do.

squirrel code

        function foo(i, f, s) 
        { 
            print("Called foo(), i="+i+", f="+f+", s='"+s+"'"); 
        } 

and this C code

C code

        #include <stdarg.h> 
        #include <stdio.h> 


        #include <squirrel.h> 
        #include <sqstdio.h> 
        #include <sqstdaux.h> 


        #ifdef _MSC_VER
        #pragma comment (lib ,"squirrel.lib")
        #pragma comment (lib ,"sqstdlib.lib")
        #endif


        #ifdef SQUNICODE 
        #define scvprintf vwprintf 
        #else 
        #define scvprintf vprintf 
        #endif 


        void printfunc(HSQUIRRELVM v, const SQChar *s, ...) 
        { 
                va_list arglist; 
                va_start(arglist, s); 
                scvprintf(s, arglist); 
                va_end(arglist); 
        } 


        void call_foo(HSQUIRRELVM v, int n,float f,const SQChar *s)
        {
                int top = sq_gettop(v); //saves the stack size before the call
                sq_pushroottable(v); //pushes the global table
                sq_pushstring(v,_SC("foo"),-1);
                if(SQ_SUCCEEDED(sq_get(v,-2))) { //gets the field 'foo' from the global table
                        sq_pushroottable(v); //push the 'this' (in this case is the global table)
                        sq_pushinteger(v,n); 
                        sq_pushfloat(v,f);
                        sq_pushstring(v,s,-1);
                        sq_call(v,4,0,0); //calls the function 
                }
                sq_settop(v,top); //restores the original stack size
        }


        int main(int argc, char* argv[]) 
        { 
                HSQUIRRELVM v; 
                v = sq_open(1024); // creates a VM with initial stack size 1024 


                sqstd_seterrorhandlers(v);


                sq_setprintfunc(v, printfunc, NULL); //sets the print function


                sq_pushroottable(v); //push the root table(were the globals of the script will be stored)
                if(SQ_SUCCEEDED(sqstd_dofile(v, _SC("test.nut"), 0, 1))) // also prints syntax errors if any 
                {
                        call_foo(v,1,2.5,_SC("teststring"));
                }


                sq_pop(v,1); //pops the root table
                sq_close(v); 


                return 0; 
        } 

Initialize Squirrel

The first thing you have to do is create a virtual machine(VM)

        HSQUIRRELVM v = sq_open(1024);

1024 is the initial stack size

squirrel stack grows automatically so this value is just a hint to the VM

Squirrel allows to define your own error handling function, this sample uses the prebuilt on from the standard IO library.

        sqstd_seterrorhandlers(v);

in order to allow functions like print() to output some text is necessary to provide

a print-function to the VM.

        sq_setprintfunc(v, printfunc, NULL); //sets the print function

where printfunc is defined as follows

        void printfunc(HSQUIRRELVM v, const SQChar *s, ...) 
        { 
                va_list arglist; 
                va_start(arglist, s); 
                scvprintf(s, arglist); 
                va_end(arglist); 
        } 

and third parameter NULL tell the VM we don't want handle the errors.

Run the script

Squirrel offers a low level API to compile and run scripts from any kind of media,

however, 90% of the time, the script will be a simple text file and you will want to run it

right after compilation. The easiest way to archieve this is to use the standard IO library (sqstdio.h).

sqstd_dofile compiles a script and runs it.

        sq_pushroottable(v);
        sqstd_dofile(v, "myscript.nut",0); 

sqstd_dofile expects an object on top of the stack(in this case the root table) that will be

used as this during the execution of the script.

Call a Squirrel function from C++

The squirrel script we are taking as example defines a function called foo.

In order to call the function first we have to retrieve it and place it on the stack.

Because the function was declared in the global scope, it is stored in the root table.

        void call_foo(HSQUIRRELVM v, int n,float f,const SQChar *s)
        {
                int top = sq_gettop(v); //saves the stack size before the call
                sq_pushroottable(v); //pushes the global table
                sq_pushstring(v,_SC("foo"),-1);
                if(SQ_SUCCEEDED(sq_get(v,-2))) { //gets the field 'foo' from the global table
                        sq_pushroottable(v); //push the 'this' (in this case is the global table)
                        sq_pushinteger(v,n); 
                        sq_pushfloat(v,f);
                        sq_pushstring(v,s,-1);
                        sq_call(v,4,0,0); //calls the function 
                }
                sq_settop(v,top); //restores the original stack size
        }

call_foo calls the foo function passing an integer, a float and a string as parameters.

Let's analyze it line by line.

First it stores the current stack size for cleaning it up after the call.

        int top = sq_gettop(v);

Pushes the root table, where the function will be fetched from.

        sq_pushroottable(v);
negative index object
-1 root table
... ...

stack situation

Pushes the string "foo" that in this case is the name of the slot that contains the function

we want to fetch.

        sq_pushstring(v,_SC("foo"),-1);

the parameter -1 specifies that the VM should compute the string length automatically.

negative index object
-1(top) "foo"
-2 root table
... ...

stack situation

Then fetches the function

        if(SQ_SUCCEEDED(sq_get(v,-2))) {

The function sq_get, pops an object from the stack(in this case the string "foo")

and uses it as key to fetch the object at position -2 from the top of the stack(in this case

the root table). If the function succeed, it pushes the result in the stack.

negative index object
-1(top) function foo(){}
-2 root table
... ...

stack situation after sq_get

now the function pushes the parameters in the stack. the root table is pushed again to set it

as this parameter.Squirrel function always have a hidden parameters this (just like C++ class memebers).

        sq_pushroottable(v);
        sq_pushinteger(v,n); 
        sq_pushfloat(v,f);
        sq_pushstring(v,s,-1);
negative index object
-1(top) string
-2 float
-3 integer
-4 root table
-5 function foo(){}
-6 root table
... ...

stack situation

Finally the sq_call function is invoked. This execute the actual call.

        sq_call(v,4,0,0); 

4 means that the function has 4 parameters(this,the integer,the float and the string).

Squirrel will then pop the 4 parameters and links. expect a function to be at the top of the stack.

the third parameters set to 0 tells squirrel that no return value is expected from the function

call. If another value than 0 would be specified squirrel would push the return value of the called function.

the fourth parameter set to 0 tells squirrel not to invoke the error handler while runtime errors occur.

negative index object
-1(top) function foo(){}
-2 root table
... ...

stack situation after sq_call

the function has been executed so now we reset the stack to the initial state

        sq_settop(v,top); //restores the original stack size

Cleaning up

previously we pushed the root table once to for executing sqstd_dofile, is time to remove it.

        sq_pop(v,1); 

at the end of the program we delete the squirrel VM

        sq_close(v); 
Not logged in. Log in

squirrel's community wiki

This is FlexWiki, an open source wiki engine.

Change Style

Recent Topics