Unable to access object after I inject it


I have a number of instances of the same class. I want to be able to use the same method on all of them. So, I wrote the following:

chai.add(chaiscript::fun(static_cast<void (Foo::*)(int, float)>(&Foo::setParameter)), “setParameter”); // add method
chai.add(chaiscript::var(std::ref(ap)), “Filt”); // add object

No errors adding them but when I try to invoke a call, e.g.

Filt.setParameter(3, 0.7);

I get the error, Script error in script:Error: “Can not find object: Filt” during evaluation at (EVAL 30, 10)

What am I doing wrong, please?



I’m guessing there’s a piece of info missing here, like perhaps you are calling


From inside of another function? When you are inside of a function you can only see 3 things:

  1. Explicitly passed parameters
  2. Other functions
  3. Global values

So, you either need to pass your ‘Filt’ object around, or you want to do:

chai.add_global(chaiscript::var(std::ref(ap)), "Filt"); // add global object.



Yeah, you’re absolutely right. Thank you. However, I think this opened up a different can of worms. Although the method name is the same, the objects are part of a hierarchy and the methods are virtual.
I’m getting a crash everytime I invoke that method and I suspect (hard to tell from the ADT tree) that the base method is being called, and there’s no such implementation for the base.


virtual methods and base class hierarchies are well supported. All you should need to do is register the base class version of the method, then use chaiscript::base_class to tell chai about the relationship.



Again, thanks for the quick response — had to read that code in github. If I am understanding correctly, I have to use that base_class template to define EVERY relationship between parents and children?
If I have 4 classes in a strict hierarchy Base, D1, D2, D3 (D2 inherits from D1, D3 from D2, etc) do I now have to define the relationship between every possible combination, i.e. <Base, D1>, <Base, D2>, <Base, D3>, <D1, D2> <D1, D3>, <D2, D3> ?
If so that sounds like combinatoric hell as the hierarchy grows.



You are correct that I do not do automatic chaining.

However I think you are over-thinking the issue. You probably don’t care about every relationship.

Just do:

base_class<Base, D1>()
base_class<Base, D2>()
base_class<Base, D3>()
base_class<Base, D4>()

This would make each derived convertible back to base, but not between each other.


Unfortunately, some of the classes in the hierarchy are hidden (i.e. defined in C++ implementation files, not headers) so I can’t actually references the ones I need.
(Throwing in forward declarations of those classes just results in the error "No matching function for call to ‘base_class’)

I might have to give up on this concept and just hardcode names to specific instances.



I’m going to try setting up a “forwarder” class instead — (I forget the design pattern name for this (Proxy, maybe), it has been too long) but keeping instances of those around might be a worthwhile workaround. Figured I’d mention it in case anybody else runs into this kind of thing.


ChaiScript <-> C++ is excellent for passing function objects around. Create them in script, create them in C++, doesn’t matter. Give you a nice level of abstraction. Probably similar to what you are implementing. Something to consider.



I’m already convinced that under the covers chaiscript can do what I need and have already created some very useful userscripts for our system. However, I’m seriously considering putting together a simpler “language” for users and using a tool that would spit out chaiscript, either by quickly hand-rolling a recursive descent parser or using something like ANTLR (downside being that I’d have to include a Java app with the product). The reason for doing this is because I would like to be able to write in the style

On ReceivedNoteEvent B3 note velocity

which makes it clear that this is a callback function and then that would get translated into something like

def B3_ReceivedNoteEvent(int note, int velocity)

If I go down that route then I’ll never actually need to expose objects because my C++ code will automatically inject the appropriate chaiscript function directly, i.e. chai.add( …, “B3_ReceivedNoteEvent”) associated with an internal object called B3