ChaiScript Tutorial (5) – Calling ChaiScript Functions from C++ and vise versa

With the really limited functionality ChaiScript has. There must be a way to expand it’s ability. In this tutorial, we are going to expend ChaiScript’s functionality by calling C++ functions in ChaiScript and the reverse.

Calling C++ functions in ChaiScript

To call C++ functions in C++ from ChaiScript requires 2 steps.

  1. Register the C++ function to ChaiScript
  2. Call it from ChaiScript

Let’s code! This is the C++ side of our code

#include <chaiscript/chaiscript.hpp>

#include <iostream>
#include <string>

void hello(std::string name)
{
	std::cout << "Hello " << name << std::endl;
}

int main(int argc, char** argv)
{
	if(argc < 2)
		return 0;
	chaiscript::ChaiScript chai;
	chai.add(chaiscript::fun(hello), "hello");

	chai.use(argv[1]);
}

And the ChaiScript side

var name = "Martin"
hello(name)

Compile it and pass the ChaiScript file as the argument to your executable. Then you should see the following screen.

2017-03-15 17-56-19 的螢幕擷圖
We are calling a function written in C++ in ChaiScript

It works as the following.

First we define the function that we want ChaiScript to be able to call. In this case, it is the function hello . Next we initialize the ChaiScript interpolator as usual using the line chaiscript::ChaiScript chai;.  Then, we add the function to ChaiScript’s interpolator so it can be called later in ChaiScript using the line chai.add(chaiscript::fun(&hello), "hello");. Here, we add the function hello to ChaiScript by the name of hello.

And, yes, That means that the name of you function does not have to be the same of the function name it is in ChaiScript. Also, notice that no signature is required when adding a function to ChaiScript. Some C++ black magic and the compiler takes care of that. You don’t need to worry about that, overloading done automatically.

After adding the function to ChaiScript. It can be called directly  from ChaiScript as a normal ChaiScript function.

Returning Value from C++

Besides calling function from ChaiScript. You can also get value back from C++. What you have to do is trivial. Write a function that returns something. And do what you do from above.

Assuming we have a function called hello that takes in a string and append it after the string “Hello “. It is implemented like this

std::string hello(std::string name)
{
	return "Hello " + name;
}

Then add the function the same way.

chai.add(chaiscript::fun(hello), "hello");

Calling hello in ChaiScript will execute the C++ function and returns a string to ChaiScript. The following code will also print “Hello Martin”.

var name = "Martin"
puts(hello(name))
puts('\n')
Screenshot_20170315_004231
Returning value from C++

More than just functions

You might be thinking. Can I call a std::function or a lambda? The answer is, Yes.

Calling a std::function is straight foreword. the following line code will do the job. Note that there should not be a & before the object.

std::function<void(std::string)> sayHello = hello;
chai.add(chaiscript::fun(sayHello), "hello");

Calling a lambda is also easy. But a bit of stuff need to be taken cared. Here is how you call a lambda

auto sayHello = [](std::string name){hello(name);};
chai.add(chaiscript::fun(sayHello), "hello");

Note that a generic lambda(a lambda with auto parameter type) cannot be used due to  the C++ compiler needs to know the type of the function at compile time. But ChaiScript is a scripting language, the type of  the parameters passed in is determined at runtime.

Calling a ChaiScript function from C++

Surely we can call a ChaiScript function from C++. As stated in the previous tutorial. A function in ChaiScript internally is a std::function. So we can get a std::function object that calls the ChaiScript function from the interpolator.

Assuming that we have a function enableSkynet in ChaiScript.

def enableSykNet()
{
	print("Skynet Enabled.")
}

then, getting and calling the function in C++ can be done by

auto enableSkynet = chai.eval<std::function<void()>>"enableSkynet");
enableSkynet();

Again, the type of the function object in C++ have to be determined at compiler time. So the type of the function have to be entered manually. (the void() part in the code.)

And, we can pass parameters from when calling a function in ChaiScript in C++. It is straightforward to do so. Write a function in ChaiScript that takes parameter, get the function from the intrerpolator, then call it.

For example, the following code sum all number from 1 to n. then prints it out.

def sumUpTo(n)
{
	var s = 0
	for(var i=1;i<=n;++i)
	{
		s += i;
	}
	print(s)
}

To call this function from C++, we get the function from the interpolator also telling the C++ compiler the parameter type we want to use passed in. Then it can be used as a normal function.

auto sumUpTo = chai.eval<std::function<void(int)>>("sumUpTo");
sumUpTo(100);

There is no limit on how many parameter

Return value from ChaiScript to C++

Returning value from ChaiScript is easy too. Write a return statement in the ChaiScript function and change stuff in C++ accordingly will do the job. The following ChaiScript code returns the sum of 1 to n.

def sumUpTo(n)
{
	var s = 0
	for(var i=1;i<=n;++i)
	{
		s += i;
	}
	return s
}

The following code calls it and get the return value

auto sumUpTo = chai.eval<std::function<int(int)>>("sumUpTo");
int s = sumUpTo(100);
std::cout << s << std::endl;

The concludes this tutorial. In the next tutorial. We are going to use global variables in ChaiScript.

Advertisements

One thought on “ChaiScript Tutorial (5) – Calling ChaiScript Functions from C++ and vise versa

Add yours

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Powered by WordPress.com.

Up ↑

%d bloggers like this: