Exposing members that are arrays


I know in other posts it was suggested to not using raw arrays or pointers, but you also hinted that it might be possible.

I have the following example C++ code that I would like to script using Chai:

struct message_content{
  int field1;
  int field2;
  int field3[3];

void sendMessage(const message_content& msg)
  // encodes and sends the message

From my chai scripts I would like to be able to create and fill in a message_content struct and then call sendMessage(). (I will have a whole series of structs, senders and receiver functions that will form an automated test system).

At the moment the following code does not work for me:

chai.add(ch::user_type<message_content>(), "message_content");
chai.add(ch::constructor<message_content()>(), "message_content");
chai.add(ch::fun(&message_content::field1), "field1");
chai.add(ch::fun(&message_content::field2), "field2");
chai.add(ch::fun(&message_content::field3), "field3");

The last line fails to compile due to the std::ref() being created to an array @ handle_return.cpp(110).

Is there any sort of work around that will enable this sort of usecase. Unfortunately I don’t have any control over the structures that I am mapping as they are auto-generated from an interface definition system.

Thanks for the awesome project by the way. I was able to get a program up and running within about 10 mins including passing data back and forth between C++ and ChaiScript.


That sounds like a bug in how I handle return values that are arrays. I’m kind of surprised the compiler is not automatically decaying the array into a pointer type. I’ll see what I can find, but my week has gotten very busy.


Ok thanks for the update, I appreciate your time. I forgot to mention in my post that I’m using Visual Studio 2013.

On VS2013 you don’t seem to be able to take a std::ref to an array type. Take the following code:

int x[3];
auto xref = std::ref(x);

This fails to compile because internally the std::ref function creates a _Callable_obj struct that has a member function that returns T. This causes a compile error when T is int[3].

The above code does compile correctly on Clang 3.5 and GCC 4.9 (using coliru), but I haven’t been able to check that ChaiScript functions as intented given this type of argument on these compilers.

Poll: What's Next For ChaiScript?

Has there been progress on this?
While i can compile when binding a class with an array-member, i cannot access it:
Error: “Can not find appropriate array lookup operator ‘[]’.” With parameters: (A6_f, const int)
or if used with var as index:
Error: “Can not find appropriate array lookup operator ‘[]’.” With parameters: (A6_f, int)


I’m sorry, I forgot about this. I have some concern that it would cause issues with indexing into other pointer types, but I’ll see if I can address it with at least a helper function to register it or something…



it’d be enough for me. wouldn’t mind having to registering it as an array of numbers.
but without knowing about the internals - the error calls it A6_f, so it seems to already know that i meant it to be an array of 6 floats.
will add some get-funcs for now.
thanks for the swift reply.


Can you post a complete example? I might be able to work with that if it’s a fixed size array, or an std::array it’s the “treat a pointer as an array” that I have a problem with.


In c++:

class ClientState {
	timestamp_t timestamp;
	unsigned int buttons;
	float axes[6];

engine.add(chaiscript::constructor < ClientState() > (),"ClientState");
engine.add(chaiscript::constructor < ClientState(const ClientState &) > (),"ClientState");

all is well, but later in script:

var cs = ClientState();
body.bodyDef.position.x = ppos.x+cs.axes[3]*0.1;

on the line that uses cs.axes[3]:

... failed: Error: "Can not find appropriate array lookup operator '[]'." With parameters: (A6_f, const int) 

so nothing fancy really, just a float[6] in a class, and using it only as an array.

edit: or do you mean complete as in compiles?


One that compiles would be nice, but that answers my questions.

#include <chaiscript/chaiscript.hpp>
class MyClass {
	static const unsigned char numData = 10;
	float data[numData];
	MyClass() {
		for(unsigned char i = 0;i < numData;i++) data[i] = 0.0f;
	MyClass(const MyClass & other) {*this = other;}
	MyClass & operator=(const MyClass & other) {
		for(unsigned char i = 0;i < numData;i++) data[i] = other.data[i];

int main()
	chaiscript::ChaiScript chai;
	chai.add(chaiscript::constructor < MyClass() > (),"MyClass");
	chai.add(chaiscript::constructor < MyClass(const MyClass &) > (),"MyClass");
	chai.eval("var myclass = MyClass();myclass.data[0] = 1.0f;");

// g++ -std=c++14 chaitest.cpp -o chaitest -ldl;./chaitest

/* result:
terminate called after throwing an instance of 'chaiscript::exception::eval_error'
  what():  Error: "Can not find appropriate array lookup operator '[]'." With parameters: (A10_f, const int) 


Ok, I’ve got something that’s working - with a caveat. The code does not work on MSVC 2013 due to a bug in their implementation of std::reference_wrapper. It seems it will work in MSVC 2015 and I know that it works fine with gcc4.6+, clang3.4+



It’s done and merged into develop now.


That’s great, thank you.


If you go to use it, make sure to look at the example for how to expose an array type here:

You have to add the array element and tell the system about those types.