2016-06-10 15 views
0

Ich habe eine Funktion wie die folgende Rückgabe einer C-Zeichenfolge von einer anderen Funktion, die eine Std :: String zurückgibt.Seltsame Ausgabe für Luajit ffi Funktion zurückgeben Zeichenfolge

const char* GetFilePath(const char* aFilename) 
{ 
    return FileSystem->GetFilePath(aFilename).c_str(); 
} 

Wenn ich diese Funktion von lua rufen nur ich Müll. Wenn ich die Funktion modifiziere, um zum Beispiel einen "Test" zurückzugeben, funktioniert es.

Ich denke, es ist, weil der zurückgegebene std :: string Destruktor aufgerufen wird und daher die Zeichenfolge löscht die C-Zeichenfolge ungültig.

Meine Frage ist, wie kann ich das verhindern? Wie kann ich das funktionieren lassen?

UPDATE: Ich exponiere diese Funktion zu Lua mit den folgenden.

local ffi = require('ffi') 
ffi.cdef[[ 
const char* GetFilePath(const char* aFilename) 
]] 

x = ffi.string(GetFilePath("Script.lua")) 
io.write(x) 

Dieser Code druckt nur einige zufällige Müll. Aber wenn ich die C-Wrapper-Funktion modifiziere, um nur eine C-Style-Zeichenfolge zurückzugeben, bekomme ich die gewünschte Ausgabe.

Update 2: Zum Beispiel, wenn ich so etwas wie die folgenden tun:

const char* GetFilePath(const char* aFilename) 
{ 
    return aFilename; 
} 

Es funktioniert wie erwartet. Auch wenn ich einige andere Funktionen verfügbar mache, die ein const char * zurückgeben. aber wenn ich folgendes tun:

const char* GetFilePath(const char* aFilename) 
{ 
    return std::string(aFilename).c_str(); 
} 

ich zufällig Müll. Meine ursprüngliche C++ - Funktion gibt eine std :: string zurück.

+0

In Ihrem update2 ist dieser Code 'return std :: string (aFilename) .c_str();' nie korrekt. Das wird immer undefiniertes Verhalten geben, ganz gleich, ob es sich um Lua-Bindungen oder irgendetwas anderes handelt. –

Antwort

2

Wenn Sie darauf bestehen, die Luajit FFI dafür zu verwenden, anstatt die CAPI zu verwenden, müssen Sie etwas komplizierteres C++ schreiben.

Das Problem ist, dass jede Funktion, die const char * in C++ zurückgibt, kann nicht durch den Aufruf c_str() auf einer lokalen oder temporären std::string erzeugt werden, da es ungültig wird, bevor lua eine Chance, es zu benutzen wird.

Der einfachste Trick, um dies zu umgehen, ist die Verwendung einer static lokalen Variablen, die nicht direkt nach der Rückkehr der Funktion zerstört wird.

const char* GetFilePath(const char* aFilename) 
{ 
    static std::string long_lived; 
    long_lived = FileSystem->GetFilePath(aFilename); 
    return long_lived.c_str(); 
} 

Es gibt einigen zusätzlichen Aufwand hier - die long_lived Zeichenfolge zugewiesen werden, bis GetFilePath erneut aufgerufen wird, oder Ihr Programm endet. Aber diese Strings sind klein, so dass dieser Overhead keine Rolle spielt.

+0

Vielen Dank für die Antwort! Das behebt mein Problem. Ich kann versuchen, meinen Code neu zu entwerfen oder den Standard lua c api wieder zu verwenden. – TheMasterMaind