I am trying to get the return value from c++ function in dart.
My c++ code is something like this
static bool is_alive() {
return true;
}
From dart, I loaded the shared lib with this native code and I am trying to call that is_alive() function.
typedef BooleanFunction = Pointer<Int8> Function();
Pointer<NativeFunction<BooleanFunction>> isAlive = (functionAddress).cast<NativeFunction<BooleanFunction>>();
Pointer<Int8> Function() isAliveFunc = isAlive.asFunction();
I called then the isAliveFunc from dart and I want the result of that functions. I tried all these ways. None of these works.
Pointer<Int8> casted = isAliveFunc()!.cast();
Pointer<Int8>? fromPointer = isAliveFunc()!;
developer.log('value : $casted');
I get the result like this Pointer<Int8>: address=0x1
How can I fetch the value from this pointer in dart ? I expect to get a 1 or 0 as the result.
For some reason you never actually call your isAliveFunc function.
Just call the function as you would any other:
Pointer<Int8> casted = isAliveFunc();
or
Pointer<Int8> casted = isAliveFunc.call();
You should also be paying attention to your Dart static analysis warnings and errors.
Your function definitions are also incorrect. is_alive returns a bool/Int8, not a pointer.
Your BooleanFunction typedef should be:
typedef BooleanFunction = Int8 Function();
int Function() isAliveFunc = isAlive.asFunction();
And the function call return should be assigned to an int:
int casted = isAliveFunc();
Related
I would like to assign lua functions to C++ function pointers or std::functions and call them at a later time. I have been searching and experimenting with lua functions (through Sol3) like so:
std::function<vec3(float, float, float,vec3)> saved_script = lua_["Idle"]["animate"];
or
vec3 (* Script)(float, float, float, vec3) saved_script = lua["Idle"]["animate"];
Thanks.
That works.
function InitScript(str)
return true
end
using func_t = std::function<bool(std::string)>;
func_t func = m_state.get<func_t>("InitScript"); // sol::state m_state;
bool result = func("some string"); // true
This is what I did.
I created a struct and a static function in my C++ code
struct ItemDefinition {
int64_t price;
};
int static getPrice(lua_State* L) {
ItemDefinition* def = (ItemDefinition*)lua_touserdata(L, 1);
printf("%p\n", def);
printf("%d\n", def->price);
return 0;
}
I also registered the function in lua and initialized an ItemDefination object.
ItemDefinition def;
def.price = 120;
lua_pushlightuserdata(lua_state_, (ItemDefinition*)&def);
lua_setglobal(lua_state_, "def");
luaL_Reg module[] = {{"getPrice", &getPrice}, {NULL, NULL}};
from my Lua script, I just simply call the function
getPrice(def)
if works fine if I just print out the def's address. So I'm sure the function get called successfully. However, if I'm trying to get def->price, I will get an error from address sanitizer "==283789==ERROR stack use after return"
I'm not familiar with both c++ and lua. Could you please help where the problem could be?
Resolve the issue, NVM. It's actually because the pointer issue.
I'm not going to get into too much of the details on the Excel side of things, I essentially took code from this example:
C++ app automates Excel (CppAutomateExcel)
solution1.cpp
So I've tried this code in MSVC and it compiles:
class foo { public: virtual void bar(){} };
int main()
{
void (foo::*p)() = &foo::bar;
}
But similar code to capture the address of the move function in Excel does not work:
int main()
{
Excel::_ApplicationPtr spXlApp;
HRESULT hr = spXlApp.CreateInstance(__uuidof(Excel::Application));
Excel::WorkbooksPtr spXlBooks = spXlApp->Workbooks;
Excel::_WorkbookPtr spXlBook = spXlBooks->Add();
Excel::_WorksheetPtr spXlSheet = spXlBook->ActiveSheet;
HRESULT(Excel::_Worksheet::*pMove)(...) = &spXlSheet->Excel::_Worksheet::Move;
<... irrelevant code ...>
return 0;
}
This has the following compiler error:
error C2276: '&': illegal operation on bound member function expression
If I remove the &, it says I should add it back:
error C3867: 'Excel::_Worksheet::Move': non-standard syntax; use '&' to create a pointer to member
Any help on what to do here would be greatly appreciated.
You say in your question "but similar code..." and then you show code in which you do not do the same thing. Try using the same syntax for setting pMove as you used for setting p in your smaller example. Try something like &Excel::_Worksheet::Move; (without the "spXlSheet->").
If you can specify the specific instance of the object for which to call the function pointer at the time that you set the function pointer as you have there, I'm not aware of such a capability. After dropping spXlSheet-> from where you set the variable, use it instead where you want to call the function pointer.
You need to declare the method pointer like this instead:
// or whatever parameter type Move() actually uses...
void (Excel::_Worksheet::*pMove)(tagVARIANT, tagVARIANT) = &Excel::_Worksheet::Move;
Then, to actually call pMove(), you would have to do something like this:
Excel::_WorksheetPtr spXlSheet = ...;
(spXlSheet.Get()->*pMove)(...);
Say that you define a callback function as such:
typedef std::function<void(float)> Callback;
And you have a function as such:
void ImAFunction(float a)
{
//Do something with a
}
Is there a way to be able to store a function without an argument then pass one to it at a later time?
Such as this:
//Define the Callback storage
Callback storage;
storage = std::bind(ImAFunction, this);
//Do some things
storage(5);
This wont work which I explain with some of my real code below.
I can get close to what I wan't if I bind the value in with the std::bind function. Such as:
//Change
//storage = std::bind(ImAFunction, this);
storage = std::bind(ImAFunction, this, 5.0); //5.0 is a float passed
This works but when I go to pass a value through the function the outcome is whatever I set it to before:
storage(100); //Output is still 5
I am basing the fact that I think this is possible on this article.
http://www.cprogramming.com/tutorial/function-pointers.html
It doesn't use the function or bind functions but it does pass pointer arguments and performs exactly what I need. The reason I don't just skip the bind function is because I am trying to store the function in a class (private) and I can't store it if it's a template because it's created with the class.
The error produced above comes from this code:
struct BindInfo {
Callback keyCallback;
int bindType;
bool isDown;
bool held;
std::string name;
};
template <class T1>
void bindEvent(int bindType, T1* keydownObj, void(T1::*keydownF)(float), std::string name)
{
BindInfo newKeyInfo = { std::bind(keydownF, keydownObj), bindType, false, false, name };
inputBindings.insert(std::pair<int, BindInfo>(BIND_NULL, newKeyInfo));
};
The error is:
No viable conversion from '__bind<void(Main::*&)(float), Main *&>' to 'Callback' (aka 'function<void (float)>'
Is this possible? Thanks in advance.
You can include a placeholder for an unbound argument:
std::bind(&Main::ImAFunction, this, std::placeholders::_1);
If you find that a bit of a mouthful, a lambda might be more readable:
[this](float a){ImAFunction(a);}
It sounds like what you're looking for is a function pointer. While I don't have a lot of experience using them in C++ I have used them in C so: Yes, it is possible. Perhaps something like this:
void (*IAmAFunctionPointer)(float) = &IAmAFunction;
The best way to think about that line is, that IAmAFunctionPointer is a pointer (hence the *), it returns a void, and takes a float. Then later:
float a = 5;
IAmAFunctionPointer(a);
You could even design it so that the callback function is passed into the method (I assume this is what you're looking for).
void DoStuffThenCallback(float a, void (*callback)(float))
{
//DoStuff
callback(a);
}
further reading: http://www.cprogramming.com/tutorial/function-pointers.html
I'm trying to expose my std::map<std::string, std::string> as a class property to Lua. I've set this method for my getter and setter:
luabind::object FakeScript::GetSetProperties()
{
luabind::object table = luabind::newtable(L);
luabind::object metatable = luabind::newtable(L);
metatable["__index"] = &this->GetMeta;
metatable["__newindex"] = &this->SetMeta;
luabind::setmetatable<luabind::object, luabind::object>(table, metatable);
return table;
}
This way it makes me able to do something like this in Lua:
player.scripts["movement"].properties["stat"] = "idle"
print(player.scripts["movement"].properties["stat"])
However, the code I've provided in C++ doesn't getting compiled. It tells me there is an ambiguous call to overloaded function at this line metatable["__index"] = &this->GetMeta; and the line after it. I'm not sure that I'm doing this correctly.
Error message:
error C2668: 'luabind::detail::check_const_pointer' :
ambiguous call to overloaded function
c:\libraries\luabind-0.9.1\references\luabind\include\luabind\detail\instance_holder.hpp 75
These are SetMeta and GetMeta in FakeScript:
static void GetMeta();
static void SetMeta();
Previously I was doing this for getter method:
luabind::object FakeScript::getProp()
{
luabind::object obj = luabind::newtable(L);
for(auto i = this->properties.begin(); i != this->properties.end(); i++)
{
obj[i->first] = i->second;
}
return obj;
}
This works fine, but it's not letting me to use setter method. For example:
player.scripts["movement"].properties["stat"] = "idle"
print(player.scripts["movement"].properties["stat"])
In this code it just going to trigger getter method in both lines. Although if it was letting me to use setter, I wouldn't be able to get key from properties which it is ["stat"] right here.
Is there any expert on LuaBind here? I've seen most of people say they've never worked with it before.
You need to use the (undocumented) make_function() to make objects from functions.
metatable["__index"] = luabind::make_function(L, &this->GetMeta);
metatable["__newindex"] = luabind::make_function(L, &this->GetMeta);
Unfortunately, this (the simplest) overload of make_function is broken, but you just need to insert f as the second parameter in make_function.hpp.