Jump to content

Use MakeExternFunction to export C++ lambda function?


photo

Recommended Posts

Posted

Currently it is possible to export a generic C++ function to UnigineScript with code similar to:

auto SomeFunction(Unigine::Variable someParam)
{
    // some logic
    return Unigine::Variable();
}
...
Unigine::Interpreter::addExternFunction("SomeFunction", Unigine::MakeExternFunction(&SomeFunction));

It would be much more convenient if we could bind to C++ lambda functions instead, especially since then it would be possible to capture some variables from the surrounding scope:

int someValue;
...

Unigine::Interpreter::addExternFunction("SomeFunction", Unigine::MakeExternFunction([=](Unigine::Variable someParam) {
    // some logic that uses captured someValue
    return Unigine::Variable(...);
}));

However I can't seem to get this syntax to work.

Do you have an example of how to export a lambda function to UnigineScript?
Thanks!

  • Like 1
Posted

Hi Scott!

Try to specify lambda return type and function argument types as template parameters:

using namespace Unigine;

static int global_variable = 21;

Interpreter::addExternFunction("SomeFunction", MakeExternFunction<Variable, const Variable &>([=](const Variable &v) -> Variable {
	return Variable(...);
}));
 

 

Posted

Hi unclebob

I've just tried compiling your example code:

Unigine::Interpreter::addExternFunction("SomeFunction", Unigine::MakeExternFunction<Unigine::Variable, const Unigine::Variable &>([=](const Unigine::Variable &v) -> Unigine::Variable {
    return Unigine::Variable();
}));

However I get the following compiler error:

Quote

1>source.cpp(264): error C2664: 'Unigine::ExternFunctionBase *Unigine::MakeExternFunction<Unigine::Variable,const Unigine::Variable&>(Ret (__cdecl *)(A0),const char *)': cannot convert argument 1 from 'rtvis::client::fe::plugin::ui::PluginMenuBar::ExposeScriptAPI::<lambda_565db0245ae61f563ff538f489911fe9>' to 'Unigine::Variable (__cdecl *)(const Unigine::Variable &)'
1>        with
1>        [
1>            Ret=Unigine::Variable,
1>            A0=const Unigine::Variable &
1>        ]
1>source.cpp(266): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>source.cpp(264): error C2660: 'Unigine::Interpreter::addExternFunction': function does not take 1 arguments

Any idea how to fix this?

FYI I'm using Visual Studio Professional 2017 15.5.7 with C++ Language Standard flag set to /std:c++17

Thanks

Posted

FWIW I'm also seeing a similar error using Unigine::MakeCallback:

int some_local_variable;

button->setCallback0(Unigine::Gui::CLICKED, Unigine::MakeCallback<void>([=]() {
  ... // code that attempts to use captured some_local_variable
}));

This gives error:

Quote

1>source.cpp(33): error C2664: 'Unigine::CallbackBase *Unigine::MakeCallback<void>(Ret (__cdecl *)(void))': cannot convert argument 1 from 'rtvis::client::fe::analysis::ui::AnalysisPluginView::RegisterGuiCallbacks::<lambda_939dbbdc65a76e8665aa9bbe2f4fe34d>' to 'void (__cdecl *)(void)'
1>        with
1>        [
1>            Ret=void
1>        ]
1>source.cpp(35): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>source.cpp(33): error C2660: 'Unigine::Widget::setCallback0': function does not take 1 arguments

Interestingly, if I remove the variable capture [=] from the lambda definition, it compiles OK, however it can't capture variables from the surrounding scope:

button->setCallback0(Unigine::Gui::CLICKED, Unigine::MakeCallback<void>([]() {
    ... // Works, but can't capture variables from surrounding scope!
}));

Do you know how to get this working with a lambda function that captures variables from surrounding scope (not just static global variables)? 

Thanks

Posted

Hi Scott,

Just checked with MSVS 2013 - and everything is working as expected. We can't add std::function into the API because it would brake the binary compatibility, sorry.

We didn't have yet much time to check how else can it be improved with MSVS2017. If there will be any additional information - we would surely let you know.

Sorry for the inconvenience caused.

How to submit a good bug report
---
FTP server for test scenes and user uploads:

×
×
  • Create New...