Get chaiscript pointer of function


#1

Hi there,

I wan’t to get a pointer of function of a defined function in chaiscript, I know it is possible to do :

var f = fun[](){print("hello")}
// cpp function with chaiscript callback
cpp_func(f)

But what I want to do is a bit more complex, I wan’t to do something like

class test
{
  def test()
  {
  }

  def f()
  {
     print("hello")
  }

  def myFunc()
  {
     // doesn't work...
     cpp_func(this.f)
  }
}

Is there any syntax to do this ?

edit :
Moreover I can’t do tricks like this :

cpp_func( fun[this]() { this.f() } )

Because this can’t be inside the capture arguments (chaiscript error : name already exists in the current context this). But if the called function is in chaiscript I’m able to capture this argument…


#2

About the this capture problem, the problem is not when we call a cpp function but when the lambda has arguments.
The folowing code doesn’t work :

class Test
{
	def Test()
	{}

	def a(Function f)
	{
		f("test")
	}

	def b()
	{
		var l = fun [this](x) { x.print() }
		this.a(l)
	}
}
var t = Test()
t.b()

If I replace the lines :

...
f()
...
// remove argument
var l = fun [this]() { "test".print() } 
...

It works.
It seems that the problem is in chaiscript_eval.hpp:L66, to solve the issue, I changed :

        if (t_locals) {
          for (const auto &local : *t_locals) {
		state.add_object(local.first, local.second);
        }

by :

            ... (L:64)
            // Check if there is this inside the locals
	if (t_locals != nullptr)
	{
		for (const auto &local : *t_locals) {
			if (local.first == "this")
			{
				const Boxed_Value *thisobjLocal = [&]() -> const Boxed_Value *{
					auto &stackVec = t_ss.get_stack_data(state.stack_holder());
					for (size_t i = stackVec.size(); i > 0; i--) {
						if (!stackVec[i - 1].empty() && stackVec[i - 1].back().first == "this")
							return &stackVec[i - 1].back().second;
					}
					return nullptr;
				}();
				if (thisobjLocal != nullptr)
					thisobj = thisobjLocal;
				break;
			}
		}
	}
       ...

       if (t_locals) {
          for (const auto &local : *t_locals) {
			  if ((thisobj && local.first != "this") || !thisobj)
				state.add_object(local.first, local.second);
          }
        }

But my first question is always open, is it possible to get a chaiscript defined function pointer.
Thanks !


#3

I’m not sure I understand your first question, but I do agree there is a bug in setting up the locals.

By “function pointer” do you mean a “function object that is bound to a specific object?”

-Jason


#4

Thank you for finding this issue.

I believe I have fixed your concerns with https://github.com/ChaiScript/ChaiScript/commit/ca87c05cd46a93c4f1aed1fbc40b609bcc0eeb37

My version of the solution does more of the checking at parse time and less at runtime, for performance.


#5

Thank you about the fix on this capture
My need is to do the equivalent in chaiscript of this cpp code (so without using lambda) :

#include <iostream>

void f()
{
	std::cout << "hello";
}

void callback(void (*fPtr)(void))
{
	(*fPtr)();
}

int main()
{
    // This line in particular =>
	void (*fPtr)(void) = &f;
	callback(fPtr);
}