Lua C API doesn't work with pointer - c++

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.

Related

How to acess the result from a function pointer in dart

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();

Lua checkudata type C++

I've been to the end of Google and back trying to solve this problem.
I have a few userdata objects that I push from C++ to Lua.
I have a function that should get the X value of either a 2D or 3D object.
When I try to get the userdata object, taking into consideration that it could be either a 2D element or 3D object, I need to be able to get the X for whichever the user chooses.
Here is what I tried:
int getX(lua_State* L)
{
Object3D* a = static_cast<Object3D*>(luaL_checkudata(L, 1, "Object3D"));
if (!a)
{
Object2D* b = static_cast<Object2D*>(luaL_checkudata(L, 1, "Object2D"));
if (b)
{
lua_pushnumber(L, b:getX());
}
else
{
lua_pushnil(L);
}
}
else
{
lua_pushnumber(L, a:getX());
}
return 1;
}
Unfortunately if the userdata type is not Object3D, it fails and exits on an lua error without continuing to try Object2D.
Therefore, it will only work in the above code if the object being passed is of type Object3D.
luaL_testudata
void *luaL_testudata (lua_State *L, int arg, const char *tname);
This function works like luaL_checkudata, except that, when the test fails, it returns NULL instead of raising an error.
The lua(L)_check* functions throw Lua errors on failure, the lua(L)_to* functions return NULL. For whatever reason, this one deviates from the naming convention and is named lua(L)_test* instead, which makes it a bit harder to find.
Your code is incomplete and doesn't compile as-is so I can't be bothered to check, but if I'm not mistaken, just replacing luaL_checkudata with luaL_testudata should make it work as intended.
Solved by using rawequal to see which class the registry matches.

Dynamically loaded library and global variables in c++

I'm trying to build a system, that uses dynamic loaded library files (.so files) as plugins in C++14. I build the project using gcc in combination with qt5.5.1 within qtcreator.
The problem I'm having is, that I don't fully understand, what dlopen() (and dlsym()) actually does and get strange behavior because of it. Here is a simplified (not executable) Version:
/*Kernel.hpp*/
class Kernel{
int loadPlugins();
}
void* sharedPointer; //The Object location is stored in here
/*Kernel.cpp*/
Kernel::loadPlugins(){
handle1 = dlopen(<file1>, RTLD_LAZY);
init_t init = (init_t) dlsym(handle1, "init"); //init_t is just a fitting function pointer
execute_t exec = (execute_t) dlsym(handle1, "execute"); //same goes for "execute_t"
handle2 = dlopen(<file2>, RTLD_LAZY);
init_t init = (init_t) dlsym(handle2, "init");
execute_t exec = (execute_t) dlsym(handle2, "execute");
}
/*<file1.h>*/
Class Test{
int func();
int field = 0;
}
/*<file1.cpp>*/
int Test::func(){/*do stuff*/}
Test* test = NULL;
extern void* sharedPtr; //use the ptr from kernel
extern "C" init(){
test = new Test();
sharedPtr = (void*)test; //store address of newly created Test-Object
}
extern "C" execute(){
/* Do Stuff */
}
/*<file2.h>*/
/*<file2.cpp>*/
Test* test = NULL;
extern void* sharedPtr; //use the ptr from kernel
extern "C" init(){
test = (Test*)sharedPtr; //get address of Testobject
}
extern "C" execute(){
std::cout << test->field << std::endl; //Working perfectly
std::cout << test->func() << std::endl //Segmentaion fault
}
The precise Error is a symbol lookup error of a member function with some mangled name (unmangled name is Kernel::test()).
What I think, that should happen:
When Kernel.loadPlugins() is called, the first library creates an object, saves its address in the main program. Library reads that address and can use it, as if it had created that object. So the field can be read and written to and the member function can be called.
What actually happens:
When Kernel.loadPlugins() is called, the first library creates said object, can use it as expected, saves its address in the main program. Library receives said address as expected, can use the field of said object as expected (it does not matter what type that field has, even other objects, like strings, worked, valgrind does not show any leaks as well), but when it tries to call func() it produces a segmentation fault.
I have two primary doubts -
First, I would like to know why that happens?
Second, I would like to know if there is a nice way to fix it?

Calling a virtual function through a pointer using async in c++

I'm new to multi-threading and have limited knowledge in programming. I want to use async function in c++ to call a virtual function. Snippets of the code are given below. Any help would be much appreciated.
class Binary_Genome: public Individual
{
public:
std::string evaluate_fitness();
}
class Individual
{
public:
virtual std::string evaluate_fitness()=0;
}
int main()
{
std::string w_list;
Individual* current_ind;
//Skipped some code here
std::future<std::string> future_strs;
future_strs = std::async(current_ind->evaluate_fitness); //Complier does not understand this line.
w_list = future_strs.get();
return 0;
}
Compilation error:
error: invalid use of non-static member function
I understand std::async(current_ind->evaluate_fitness) is incorrect syntax. However, I don't know what the correct syntax is. The code works perfectly without async (w_list = current_ind->evaluate_fitness()). Thanks for the help.
Even if it were to compile, you would get memory error since Individual* current_ind; doesn't initialize the pointer. currently it points to garbage memory address.
yo ucan use pointers to objects in std::async liek that:
Object obj;
Object* pointer = &obj;
auto fut = std::async([pointer]{ return pointer->returnSomthing(); });
make sure that obj is alive as long as the async function runs. std::shared_ptr is extremly suitable for that.

How to pass variables to lua function in cocos2d-x?

I am trying to call lua functions in cocos2d-x. However when I try to pass some variables to lua functions. My program stopped at lua_call().
My function:
const char* getData::callLuaFunction(const char* luaFileName,const char* functionName){
lua_State* ls = CCLuaEngine::defaultEngine()->getLuaStack()->getLuaState();
std::string filefullpath = CCFileUtils::sharedFileUtils()->fullPathForFilename(luaFileName);
const char* pfilefullpath = filefullpath.c_str();
int isOpen = luaL_dofile(ls, pfilefullpath);
if(isOpen!=0){
CCLOG("Open Lua Error: %i", isOpen);
return NULL;
}
lua_getglobal(ls, functionName);
lua_pushstring(ls, "einverne");
lua_pushnumber(ls, 2);
lua_pushboolean(ls, true);
lua_call(ls, 3, 1);
const char* iResult = lua_tostring(ls, -1);
return iResult;
}
Function in lua file:
function luaLogString(_logStr,_logNum,_logBool)
    print("Lua string from C:",_logStr,_logNum,_logBool)
    return "call lua function OK"
end
Edit:
I have found lua_call is not protected. lua_pcall function is safer. And after I changed to lua_pcall. Errors show that attempt to call global '聽聽聽聽print' (a nil value)
Actually I found the problem.
I delete four space before print function in lua file and everything is OK.
And I suggest newbie to use lua_pcall rather than lua_call. Because if there is an error when calling lua_call , this function will call exit(EXIT_FAILURE) and shutdown host program without giving an error message.
The difference between lua_pcall and lua_call
English version
Chinese version