About ChaiScript

ChaiScript is the first and only scripting language designed from the ground up with C++ compatibility and modern design in mind. It is an ECMAScript-inspired, embedded functional-like language.

ChaiScript is licensed under the BSD license.

Download

Version: 3.1.0 Released: 6/18/2011

Source (tar.bz2)
Source (zip)
Windows
Linux
MacOSX

ChaiScript Questions

Function names to avoid?

Hi,

Is there a list somewhere of function/member names to avoid? I just spent some time poking at an issue where I had a method -- int DisjointSets::find(int) -- which would always give me an error when called in a script saying that it couldn't find a matching function. I rename to a different name, such as int DisjointSets::parent(int) -- and it works fine. I guess all I really needed to do was probably change the bound name, not the underlying function name.

You are running into an issue

You are running into an issue that I've been debating how to address. The problem is that functions are preferred in the order they are declared, so the built in chaiscript functions are being called and the function call itself is a match, even tho something further down in it fails.

My proposed solution is to not blindly call functions in the order they are declared, but instead to sort them as they are added to the engine such as:

  1. Typed C++ Functions
  2. Typed C++ Functions with const parameters (ie, const members)
  3. Guarded chaiscript functions
  4. Unguarded chaiscript functions

This way, the most specific function will be tried first, leading to the least specific functions.

There's been some disagreement amongst the developers as to the order of the function calls, that the above is what makes the most sense to me. Using the above, the user (such as yourself) can provide your own specific implementation of any existing function name.

-Jason

Type safety almost?

Interesting... one of these days I'll try and understand more of the internals. Reading what you posted here, am I inferring too much to think that I would theoretically be able to have two different working versions of a function? Almost sort of type safe, I guess?

Also, if I wanted to play with this idea a bit, which files would I be looking at? It might be a good exercise for me to mess with this.

Another thing I realized since posting is that I could probably use get_state to dump out the list of functions for myself.

ChaiScript functions and C++

ChaiScript functions and C++ functions can live together in several ways using guards and types, yes.

C++ function calls are always type safe, it's perfectly fine to register:

void somefun(int);
void somefun(float);
 
chai.add(fun<void (int)>(&somefun), "somefun"); // the template parameters are necessary to avoid ambiguous function pointer error
chai.add(fun<void (float)>(&somefun), "somefun");

If you want to add chaiscript functions that also overload, you can do that with function guards:

def somefun(x) : (x.is_type(string_type)) {
  // I get called if x is a string type
}

There are examples in the exception_guards.chai, object_method_guards.chai and object_constructor_guards.chai unit tests. They are also used extensively in the chaiscript prelude (chaiscript/language/chaiscript_prelude.hpp).

No matching function to dispatch

const char * getField(int i,const char * j)
{
 std::string msgcontent=j;
 const char * ret=msgcontent.data();
 return ret;
}
  chai.add(chaiscript::fun(&getField), "getField");

with
test.chai:

var  msgtype=1;
var  msgsqnr=2;
 
print(getField(msgtype,"header"));
print(getField(2,"notice"));

gives:
Error: "No matching function to dispatch to with function 'getField'" in 'test.chai' at (4, 7)

If I replace 'const char *' with 'std:string' it works. But I can't use std:string in function declarations within my enviroment (conflict with a different library). Any help is appreciated.

Advanced type conversions

I've been pondering more advanced conversions, like you pointed out. Ones that would feel natural to a C++ developer, but would not necessarily be built into the language. I'm not convinced of the best way to do it yet, or if it's even a good idea.

As a compromise, I've exposed the .data() and .c_str() methods to the string class.

Before I give an example, I'd like to point out two potential issues with your above code. First, c_str() is the recommended method, not data() because c_str() is guaranteed to be null terminated, the other is not.

Second, in your example, you have a pretty bad memory error. You are creating a string object and returning a pointer to its internal data. As soon as "return" executes your string (msgcontent) is popped from the stack and the pointer you are returning is no longer valid.

Now for how you might use the new methods:

getField(2, "notice".c_str());

Thanks for the advice

With the latest version it works now. But one minor error: using print shows only the first char of the returned string. When I change the c++ code to:

chaiscript::ChaiScript mchai;
chaiscript::Boxed_Value getField(int i,const char * j)
{
 msgcontent=j;
 char *ret=new char(msgcontent.length()+1);
 strcpy(ret,j);
 return (mchai.eval("\""+msgcontent+"\""));
}

here the print function works.
whereas

char *getField(int i,const char * j)
{
 msgcontent=j;
 char *ret=new char(msgcontent.length()+1);
 strcpy(ret,j);
 return ret;
}

print shows only the first char.

bad cast with functor

My script (test.chai) looks like this:

def func() {
	var msg=getField("header",0)
 print(msg)
}

in C++ (VS 2010)
I'm using:

(m_chai is static)

static 	boost::function<void ()> func;
 
  m_chai.add(fun(&finddec), "finddec"); 
  m_chai.add(fun(&getField), "getField");
  m_chai.add(fun(&setField), "setField");
  m_chai.eval_file("test.chai");
  func = m_chai.functor<void ()>("func")

the last statement throws 'bad cast' Exception.
Any ideas, what I did do wrong?

--- edited by lefticus to make the code show up better

functor calls

There's been several posts that make reference to static chaiscript objects and your example is setting to a static chaiscript::function. I just want to point out that I have a hard time recommending using chaiscript and related objects as statics. I would say there's a good chance that you will at some point run into problems during object destruction on some platform (during application shutdown).

That said: your functor<> issue is fixed in SVN, and I added a unit test to make sure I don't re-break it. Fundamentally, the problem is that you had a const function variable "func," and the functor<> call was expecting a non-const value. It was simply a bug.

You can either check out SVN, or you can make a temporary variable that should work the same:

def func() { print("Hello World"); }
var func2 = func;
boost::function<void()> f = chai.functor<void ()>("func2");

-Jason

with new version dll load error

I understand the bug. So I used the latest svc version, but now I'm getting this error:
5820 ERROR App::load() failed to load AHDProxyPlugin.dll: %1 is not a valid Win32 application.
(the chaiscript is handled within a dll).
I had the same error with the previous version, which could be corrected with:
#define CHAISCRIPT_NO_THREADS

BTW: your workaround does work. Thanks

Update: after some further testing, I found that the access in a multi-threading environment is not possible.
I commented #define CHAISCRIPT_NO_THREADS out, but the program will not load (see above 5820 Error) as dll and start not at all as Console-Application. The culprit seems to be: libboost_thread-vc100-mt-gd-1_43.lib. Whenever this lic is linked to my program, it can't neither be loaded or executed.

Any ideas?

How do you link with the boost libs?

My main testing platform is

My main testing platform is Windows 7 with Visual Studio 2008 and boost 1.40 (I think). I don't have time to double check right now, but the build should be using the built in automatic linking that boost::thread does to the static version of the libs.

If you're interested in helping me figure out the difference between your setup and mine, there are two things that would help a lot.

  1. Running the unit tests: if you can get the CMake project compiling and build the project then build "RUN_TESTS" and let me know what compile warnings are generated and which unit tests fail
  2. Re-creating the problem: can you make the smallest possible example that you can which re-creates this problem and post it to the chaiscript.googlecode.com project tracker? Then I can use your project on my setup and see if I have a similar problem.

I just realized the problem may be more simple than that. It kind of sounds like you are linking to the boost_thread dll dynamically, but when you start your app it simply cannot find the dll. Windows looks in the same location of the EXE, the system PATH, and I think you can set runtime directory search directories in the visual studio project settions. For a simple test, just copy the dll into the same dir as your exe and try again.

Thanks!
Jason

Why it's linking to boost_thread

I just realized why it is still linking to boost::thread when you are using the latest SVN. It is because I forgot to #ifdef around the boost/thread/shared_mutex.hpp include in dispatchkit/dynamic_cast_conversion.hpp. By leaving this include in, the boost automatic linking is kicking in. I'll fix that this afternoon. I'm still guessing your real problem is that the boost dll's cannot be found at runtime.

-Jason

I could compile/link and run

I could compile/link and run your sample application. I double checked my executable and couldn't find any unloadable dlls. Actually the linker asked expiciltly for the static library.
I'll try to make a small project to reproduce the error. Thanks.

OK, here are my findings:
I created an empty project and filled the necessary paths and lib names and now the error is gone.
I think there might be a conflict between boost and VS2010 libs.

throw an exception under vc71

When using vc9(vs2008) to compile cs, it works fine.But when I try to use vc71(vs2003),it throw a runtime excpetion.
source:
int i=50;
chai.add(var(&i), "i");
chai.eval("i = 5;");
//chai.eval("var j=5");//throw exception
chai.eval("var j");
chai.eval("j=5");//throw exception
Exception: C0000005 at 00008A40
EXCEPTION_ACCESS_VIOLATION
reading at 00008A40
breakpoint:
boost:: function_template.hpp line:988
return reinterpret_cast(vtable)->invoker
(this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
proxy_functions.hpp:line527
return (*begin->second)(plist);//the object's functor.obj_ptr point to $00008A40.Obviously, it is a wild pointer

Supporting VS2003 is not high

Supporting VS2003 is not high on my list, however, it *should* work, since vs2003 is supported by boost, and we rely heavily on boost.

If you would make a bug report on chaiscript.googlecode.com, I'll do my best to look into it when I next go to work on vs2010 support - to make sure I reduce any new warnings found there.

-Jason

Is it possible to access native types from C++

Hello again.

I want my users to be able to create types with chaiscript and for me to be able to retrieve the type information - mainly the attribute information.

Is it in any way possible?

Also is it at all possible to force a var or attribute to be of a certain type (strong typing)?

Thanks
Sebastian

yes, dynamic objects can be shared

There are a variety of techniques that can be used to share data between chaiscript defined objects and C++. I've just checked in a unit test to verify that it all worked, and provide some examples.

Regarding forcing a variable to be a certain type or not, let's start by clarifying terminology. Hopefully I have this right, but ChaiScript is a strongly typed dynamic language. The variable type is determined at runtime, but once it is set, it is set permanently. There are very few automatic type conversions. Conversions between pointer, reference, const, boost::shared_ptr happen automatically, whenever they safely can. Pointers that would require modifying the underlying type (ie, int->float) do not happen automatically.

There is exactly one type of variable declaration in ChaiScript, the "var" that has its type set on the first assignment operation.

However, you can force something to be a certain type during a function call by using function guards, like:

fun test(x) : x.is_type(int_type) {
 
/* do something */
 
}

Hope that helps.

-Jason

I guess I can work with that

I looked into Dynamic_Object and it can satisfy most of my needs.

I'm looking to use chaiscript as a scripting language for a kind of a database engine.
And it would be useful to allow the user to create types using the standard mechanism and for me to be able to store data using those types. The Dynamic_Object will allow me to store the object and it's associated data.
However I have still to decide whether weak typing is good enough for me. If not this method will not allow for creating a schema that can be reused (How can you compare objects if every instance can store different type of data under the same attribute name?). It would have been best if during the creation of the type there was the option to decide which type each attribute will have before instantiating the object.
Like (formal):

Attribute Definition ::= "attr" class_name "::" attribute_name
                       | "attr" class_name "::" attribute_name type_name

And a sample:

attr Rectangle::Height int

If the user uses this notation then values assigned to Rectangle::Height will be converted to int if possible or an exception is thrown (or any other predictable behavior).

Unless you are willing to add this behavior I think I will still use chaiscript but I will produce a different mechanism for creating user defined types that can be stored in that database.

Thanks
Sebastian

I see your point

We designed ChaiScript foremost as a tool for tying together your C++ objects, and did not initially consider that you would want to define types in ChaiScript.

Then, as we got further along and decided to give types a try, we thought they should be in the spirit of the rest of ChaiScript and very free form. If you want something rigid, you should define it in C++, not in ChaiScript.

However, I see your point about wanting to create types that are passed back from ChaiScript land into C++ land.

Your proposal is interesting, but I don't think it would ultimately solve your problem, because the dynamically typed attr would still exist. The user could ignore that option and still make things dynamically typed.

Perhaps requiring the user to provide a typemap would work for you? This is something you could validate at runtime and perform any conversions that you wanted to based on what the user specified.

attr Rectangle::type_map
attr Rectangle::height
attr Rectangle::width
fun Rectangle::Rectangle() { this.type_map = ["height":int_type, "width":int_type]; }

This would make you do a little bit more heavy lifting, but by requiring the user to provide a type_map attribute, you could reject an object simply on its being missing. Then, you could further use the type_map as a driver to determine which attributes should get stored and how they should get stored.

This would allow the user even to use internal attributes for whatever purposes he has in mind, but will never get stored by your database tool.

I'm sure there are unanswered questions about the best way to extract/access/convert the stored data that we could help you with.

It's at least an idea, anyhow.

Just out of curiosity, is this a closed or open project? Is it something we would like to add to the list of projects using ChaiScript?

That is possible

I was thinking of using a type map in a little different way. How ever this still requires the user to specify the types in this way which is a little cumbersome and it has another problem still.
The main problem is that in this way the language and engine are not used to enforce any kind of value assignment correction. This is not a major problem since I can reject a variable using the type when it is used by the db engine if the values of attributes don't fit the specification or if there isn't a full map declared but it's less elegant and also it's a late check and it's always best to capture errors early. Also the user can later change the map without a problem and accidentally or deliberately force wrong value insertion (This can be avoided by an error check not just against the type but also against the type definition in the DB but that takes the error checking even further down the pipeline)

If you would add the option to specify the type of an attribute I was thinking in using it in one as follows:

Supply from C++ to Chaiscript a function called CreateType that will accept a type name and a map in the form you specified. This function will then create a Chaiscript block to define this type with the strong typing and register it with the db engine. This way the language and engine can be used to enforce the safety of assignments. And every time the db engine is loaded the type will be reloaded.

Another option will be to supply a RegisterType class that will work with the option you suggested but in that way we will not benefit from early error detection.
If you can support strong typing then at least the next time the db engine is loaded the type safety will be enforced.

So I see it's not a must have but for me it's a really really nice to have.

Is it hard to implement?

Thanks
Sebastian

ChaiScript really doesn't care about types

The fundamental problem is that ChaiScript itself really doesn't know or care about types at all. Internally it only passes around Boxed_Value objects.

Every operation that occurs eventually gets dispatched to a registered C++ function (even 5 + 5). During the dispatch process the types are unboxed and the function call that matches the boxed object(s) is eventually called. At the point that C++ is called, ChaiScript is in many ways more strongly typed that C++, allowing for far fewer automatic conversions.

While your request seems reasonable, and doesn't appear to be difficult on the surface, it would essentially mean adding an entire type system where there currently is not one.

This is why I suggested making the type map and checking it on the C++ side, where types are more natural to work with. (Note: int_type is a const global object automatically created when a type is registered with the system, it is of the C++ type Type_Info).

ChaiScript does support some type introspection, working with the previously mentioned Type_Info objects. Examples:

5.get_type_info().is_type_const(); // true
5.is_type(int_type); //true

All that being said, it would be possible to add a special variable to Dynamic_Object that was a type map of some sort and provided type validation when values were set. However, I'm not convinced that it has a place in ChaiScript.

The question is somewhat technical - it would add a lot of overhead where there currently isn't any; and some what philosophical - does it even belong in ChaiScript? I'm leaning towards not. But if anyone else chimes in and this becomes a common request, we can reevaluate it.

-Jason

Non extendable classes

First let me say thanks and Hello.

My question is whether there is a way of registering a class with chaiscript that cannot be further extended by a user script?

Thanks
Sebastian

No, this is not possible. In

No, this is not possible. In ChaiScript, technically, methods do not exist; only functions exist.

So, a method call like:

obj.somefunc();

Is translated to:

somefunc(obj);

So, fundamentally, the user will always be allowed to add functions that can operate on your class. This means that the method sugaring we perform essentially means that all classes are always extendable, inside of script.

Unless I miss your meaning. What affect are you going for? What is your use case?

I see your point

I understand the explanation and I agree it should not pose a problem. After looking through the docs again I can see that there is no implicit access to members I don't explicitly register so it's OK. I was really worried about users gaining access to protected or private members but I see it can't be so.

error with functor call

OK having that previous problem with variables I tryed to implement my function via functor call.
(so whole script is 1 function)

fun(meta,dicom)
{
  print(meta.srcAeTitle);
}

ProcessDES now looks like this

	boost::call_once(&g_chaiInit,g_chaiInitOnce);
 
	g_chai.functor<void(DcDirMetaInfo_ptr,DcElemList_ptr)>(des)(pMetaInfo,pElemList);

however I'm getting an exception/error when running this (at least its not a crash)

Unable to pop global stack

any idea why ??

Im thinking that both my

Im thinking that both my errors are caused by the same thing.
(like some portion of the stack is not being initialize)

any idea why is this

any idea why is this happening ?
and whay can i do to workaround it ?

Please post a bug report

It'd help if you could post all of your source files as a bug report to chaiscript.googlecode.com. This way I can try to reproduce the problem and see where the error is. I'll do my best to debug it this weekend, or maybe tomorrow afternoon.

Thanks!

Thanks for the bug report.

Thanks for the bug report. I've fixed the problem in SVN. You were correct that the stack was not being properly initialized in the case of adding objects to the stack from C++ during multithreading.

Crash

I'm getting crash when trying to add a shared_ptr<> variable (first variable)
to the chaiscript.

it seems like its accessing non exisiting index or element.

      void add_object(const std::string &name, const Boxed_Value &obj)
      {
        StackData &stack = get_stack_data();
        validate_object_name(name);
        stack.get<0>().erase(name);
        stack.get<1>().back()[name] = obj;
      }

it happens on last line of this method.

this is the setup (processDES can be called from multiple threads )

static chaiscript::ChaiScript g_chai;
static boost::once_flag g_chaiInitOnce = BOOST_ONCE_INIT;
 
void g_chaiInit()
{
	g_chai.add(chaiscript::fun(&parseHex),"hex");
	g_chai.add(chaiscript::fun(&getTagValue),"getTag");
	g_chai.add(chaiscript::fun(&setTagValue),"setTag");
}
 
void processDES(DcDirMetaInfo_ptr pMetaInfo,DcElemList_ptr pElemList,const string& des)
{	
	boost::call_once(&g_chaiInit,g_chaiInitOnce);
 
	g_chai.add(chaiscript::var(pElemList),"dicom"); // This is the call that crashes in add_object
	g_chai.add(chaiscript::var(pMetaInfo),"meta");
 
	g_chai.eval(des);	
}

any ideas ?

I'm getting exactly the same

I'm getting exactly the same issue.

I'm using boost 1_37_0 with mthreading

Adding any var from c++ causes a crash in add_object, can't solve it so far

I updated to Revision 532,

I updated to Revision 532, seems to fix this

Standard Math Library?

yet another question. Is there a standard math library ready to be included? For time to time functions like sin, cos, exp .... just come handy.
And a related question, is there any way to specify 1.0e-6 as a double (without typing 0.000001) ?

Number representations

To my memory, there aren't yet ways to do number literals like you describe, though it shouldn't be too difficult to support them.

Performance

Hi there , I love ChaiScript! But, will it see some performance boosts in the future?
Especially for-loops (C-style) seems to be very slow.

Performance and flexibility

In ChaiScript, we intentionally focused on flexibility over performance. Why? Let's think about how you might use a scripting language in a C++ application:

You build up your C++ app, but realize parts should be runtime configurable. These types of things might be settings, business logic, or game scripts.

These call back into the engine to fire off the events or set the values for you. The script itself is merely a set of calls back to the main application.

In ChaiScript, we went one step further. The entire script is calls back to the ChaiScript engine and your application. Every addition, every step of the loop, is all calling back to ChaiScript. This makes it generally less performant, but in return you get the ability to augment what each script does to the nth degree.

We chose to put less restrictions on the programmer. We could have tightened things down and prevented that level of modification, and for our efforts we might have gotten something of a speed increase, but in our opinion, if you're using ChaiScript for time critical things, you're using it wrong. Put the time critical sections in C++ where they will always work best, and fire them off from your script.

Hope that helps.

troubles with binding

Hi there! I like ChaiScript - it's really comfortable way to bind functions in scripts. But I have trouble with binding:
I'm trying to bind function (Irrlicht engine):

In code:

IAnimatedMesh* LoadAnimMesh(io::path path)
{
return smgr->getMesh(path);
}

In main():

ChaiScript chai;
chai.add(fun(&LoadAnimMesh),"LoadAnimMesh");
chai.eval_file("C:\\main.chai");

In main.chai:

var x = LoadAnimMesh("C:\man.b3d")

But, when I tried to run, I'm received unknown exception. Please, tell me, where the problem can be.
Thanks in advance.

Type on your main.chai

It would appear that you have a typo in your main.chai:

var x = LoadAnimMesh("C:\man.b3d")

should be:

var x = LoadAnimMesh("C:\\man.b3d")

Normal C++ escaping rules apply.

oh, such a stupid typo -_-

oh, such a stupid typo -_- facepalm.jpg. Thanks.

chaiscript and boost::signal

hi, i tried to get chaiscript working with boost::signal and ended with this implementation (subclass boost::signal and implement some extra stuff for chaiscript).
http://zoadian.pastebin.com/e0NPDZQZ
it works, but is there any better solution?
wasn't able to find anything about how to bind templateclass members.

Thanks,
-suicide

Looks good to me

We should post your example for others to look at. Using the template to help you register the signal functions is what we needed to do when exposing std container classes.

Unfortunately there is not (and cannot be) a more generic way of exposing templates because we need to know the function pointer address of the functions we want to call at compile time. The only way to know these addresses is to instantiate the templates that are being used, and get the functions from them, as you did.

The important thing to realize, as you did, is that a template member is just like any other function, you just have to be explicit about which instantiation of the template you are referring to.

-Jason

boost::signals within chaiscript

ok i cleaned it up a bit.
http://zoadian.pastebin.com/TX6MaPYt

any idea how to call the signal from within chaiscript?

in c++ it would be

  PSignal<void ()> sigUpdate;
  sigUpdate(); //call all connected slots. how to call it in chai?

post it as a example whereever you like ;)

my wish for next chai version: reduce compiletime (sourcefiles/lib)

thx, suicide

Re: emitting signal.

We don't have any support for operator() in chaiscript, which is an interesting point that I will make a note of.

You would want to do something like:

chai.add(fun(&PSignal<void ()>::operator(), "emit"));.

Then in your chaiscript you could emit the signal explicitly:

mysignal.emit()

I'll look more closely at your example as soon as I get more time and see if I cannot make any more suggestions.

I've been considering a set of optional libraries that ship with chaiscript, like the stl extra that is currently there. boost::regex and filesystem were also considerations. boost::signal might be a good one too. You're showing that it could be a great way of hooking together c++ and chaiscript.

Regarding compile time, just wait :).

In all seriousness, 95% of what we need to do cannot really be done in compiled library code, but there are some techniques for making recompiles of your application faster. I should publish some docs on that. The gist of it is that you want to include ChaiScript in your main.cpp, then have a mylib.cpp that creates and returns a chaiscript::module object. Your this way, main.cpp (and the core of chaiscript) only needs to be recompiled rarely, and you make all of your changes inside your mylib.cpp.

-Jason

variable scope

var foo = 100
def barfunc()
{
  print(foo)
}
print(foo) // prints "100"
barfunc() // Eval_error, Can not find object: foo.

shouldn't `foo` be a global variable that can be resolved inside barfunc(), so calling barfunc() prints "100", too?

is this the intended behavior?

Good question

In ChaiScript there aren't global variables. You can register a constant value in your C++ application that is global, but you can't make a variable that all functions can see.

If you're curious why:

The short answer is that global variables aren't good practice.

The long answer is that we liked the idea of reusable functions in ChaiScript. The easiest way to make reusable functions is to always have a function's parameters be explicit, so you can just call it from any context and know you're passing in everything it needs.

The even longer answer is that ChaiScript is automatically thread-safe. If you take the same engine and call scripts in different threads, this should, in theory, "just work". Having global variables makes this automatic safety difficult and the implementation hairy (since now some variables would be handled differently than others).

global variables

class GlobalVariableHelper
{
public:
  Boxed_Value & __get_global(std::string const & name)
  {
    // require read-lock for thread-safe
    return _M_globalvars[name];
  }
 
  void __set_global(std::string const & name, Boxed_Value & value)
  {
    // require write-lock for thread-safe
    __globalvars[name] = value;
  }
 
private:
  std::map< std::string, Boxed_Value > _M_globalvars;
}
 
...
GlobalVariableHelper gvhelper;
chai.add(fun(&GlobalVariableHelper::__get_global, gvhelper), "get_global");
chai.add(fun(&GlobalVariableHelper::__set_global, gvhelper), "set_global");

and in chaiscript:

set_global("foo", 100); // foo = 100;
set_global("foo", get_global("foo") + 10); // foo += 10

global variable

Probably the best way to get a "global variable" is to not make it a literal variable. Instead register a getter and setter for the variable you want to be globally visible. These functions will be global, so it's up to you to maintain thread-safety, but it will be visible to all threads.

===

oops, someone edited my post instead of reply.

My bad

Who thought it was a good idea to give me admin privs? Sorry about that.

How can i expose derived classes?

How can i expose their functions to chaiscript?

class Class1
{
public:
	Class1(){}
	virtual ~Class1(){};
	void Print1(){std::cout << "Print from Class1" << std::endl;}
};
 
class Class2 : public Class1
{
public:
	Class2(){}
	virtual ~Class2(){}
	void Print2(){std::cout << "Print from Class2" << std::endl;}
};
 
Class2 * pClass2 = new Class2;
 
Class2 * getClass2(void)
{
	return pClass2;
}
 
void init()
{
	Chai.add(fun(&Class2::Print1), "Print1");
	Chai.add(fun(&Class2::Print2), "Print2");
	Chai.add(fun(&getClass2),"get");
 
}

get().Print2() works fine
get().Print1() does not - "No matching function to dispatch to" during evaluation at (1, 7)"

that should work...

I'll look into it this evening, not sure why you would have a problem with that one.