I have a function like the following returning a c-string from an another function returning a std::string.
const char* GetFilePath(const char* aFilename)
{
return FileSystem->GetFilePath(aFilename).c_str();
}
If I call this function from lua I only get garbage. If I modify the function to return for example a "Test" it works.
I think it is because the returned std::string's destructor will be called and therefore delets the string making the c-string invalid.
My question is how can I prevent this? How can I get this working?
UPDATE: I expose this function to Lua with the following.
local ffi = require('ffi')
ffi.cdef[[
const char* GetFilePath(const char* aFilename)
]]
x = ffi.string(GetFilePath("Script.lua"))
io.write(x)
This code just prints some random garbage. But if I modify the C-Wrapper function to just to return a C-Style string I get the desired output.
Update 2: For example if I do something like the following:
const char* GetFilePath(const char* aFilename)
{
return aFilename;
}
It works as expected. Also when I expose some other functions returning an const char*. BUT if I do the following:
const char* GetFilePath(const char* aFilename)
{
return std::string(aFilename).c_str();
}
I get random garbage. My original C++-Function returns an std::string.
If you insist on using the luajit FFI for this instead of using the C api, you are going to have to write some more complicated C++.
The issue is that, any function that returns const char *
in C++, cannot be generated by calling c_str()
on a local or temporary std::string
because it will become invalid before lua gets a chance to use it.
The simplest trick to get around this is to use a static
local variable, which won't be destroyed right after the function returns.
const char* GetFilePath(const char* aFilename)
{
static std::string long_lived;
long_lived = FileSystem->GetFilePath(aFilename);
return long_lived.c_str();
}
There's some extra overhead here -- the long_lived
string will be allocated until GetFilePath
is called again, or your program ends. But these strings are small, so this overhead doesn't matter much.