luabind, return std::vector funktioniert nicht korrekt

pointhi

Erfahrenes Mitglied
Ich hab eine Funktion definiert die einen std::vector zurückgibt:

C++:
std::vector<int> readFromSlave(unsigned int _bits) {
    std::vector<int> helpvector;      
    helpvector.push_back((unsigned char) 10);         
    helpvector.push_back((unsigned char) 20);        
    helpvector.push_back((unsigned char) 30);         
    helpvector.push_back((unsigned char) 40);         
    return helpvector;     
}

und hab diese in Lua mithilfe von luabind registiert:

C++:
x.def("readFromSlave", &readFromSlave, luabind::return_stl_iterator);

Dann rufe ich diese Funktion in Lua auf:

[LUA]vector = readFromSlave(500);

for value in vector do
print(value)
end[/LUA]

und bekomme z.B. das als ergebnis:

Code:
27421936
0
30
40

(ich hab das ganze gekürzt, der komplette Quellcode ist hier (mit viel für dieses Problem unnötiges zeug).

Die Frage ist: Warum wird die korrekte anzahl an elementen erkannt, diese aber nicht korrekt ausgegeben (bei unsigned char als rückgabetyp ist es noch schlimmer)

mfg, pointhi
 
Zuletzt bearbeitet von einem Moderator:
Hallo pointhi

Einfaches Problem, umständliche Lösung:
Dein vector ist auf dem stack und existiert nach der Funktion nicht mehr. Der Speicher des Vektors scheint nicht überschrieben worden zu sein, daher stimmt die Anzahl nocht, der Speicher deiner Elemente mittlerweile schon, daher falsche Zahlen.

Damit richtige Zahlen kommen, kannst du temporär folgendes probieren:
C++:
std::vector<int> readFromSlave(unsigned int _bits) {
    std::vector<int>* helpvector = new std::vector<int>(); 
    helpvector->push_back((unsigned char) 10);         
    helpvector->push_back((unsigned char) 20);        
    helpvector->push_back((unsigned char) 30);         
    helpvector->push_back((unsigned char) 40);         
    return *helpvector;     
}

Damit wird bewusst ein Memoryleak erzeugt, aber du solltest zumindest korrekte Ausgaben erhalten.

Viele Grüsse
Cromon
 
Meines wissens wird beim return eine kopie vom lokalen objekt erstellt. Ich gebe ja keine referenz oder einen pointer zurück. Wie willst du sonst objekte mithilfe von Funktionen zurückgeben?

Ich hab den workaround mal ausprobiert:

Die Ausgabe ist:

Code:
0
0
30
40

Es ist jetzt kein zufallswert mehr am anfang, aber die ersten beiden zahlen funktionieren noch immer nicht
 
Guten Morgen,

ich habe von Lua oder Luabind keine Ahnung, hat mich dennoch interessiert und ich bin auf das hier gestoßen:

http://stackoverflow.com/questions/7396856/luabind-0-9-1-uses-stl-iterator-only-show-one-element

Da wird auf eine ähnliche Symptomatik eingegangen.

In der Doku wird im Beispiel eine globale Struktur um die Nutzdaten gewrapped (http://www.rasterbar.com/products/luabind/docs.html#return-stl-iterator) - um das Problem der Nicht-Existenz zu umgehen.

Wäre es also möglich, dass return_stl_iterator nur mit globalen Containern korrekt umgehen kann?
 
So wie es aussieht brauch ich einen user defined converter, der einen std::vector von zu einer Array/Lua Table konvertiert:

http://www.rasterbar.com/products/luabind/docs.html#adding-converters-for-user-defined-types

Die Frage ist jetzt wie das funktioniert:

Mein erster versuch ist:

C++:
namespace luabind {

    template <>
    struct default_converter<std::vector<int> >
    : native_converter_base<std::vector<int> > {

        static int compute_score(lua_State* L, int index) {
            return lua_type(L, index) == LUA_TNUMBER ? 0 : -1;
        }

        std::vector<int> from(lua_State* L, int index) {
            return std::vector<int>(0);
        }

        void to(lua_State* L, std::vector<int> const& x) {
            //lua_pushnumber(L, x.value);
        }
    };

    template <>
    struct default_converter<std::vector<int> const&>
    : default_converter<std::vector<int> > {
    };
}

Diese soll noch nichts machen, aber es wird noch immer eine Fehlermeldung zurückgegeben (die durch das deaktivieren des luabind::return_stl_iterator aufgetreten ist):

Code:
std::runtime_error: 'Trying to use unregistered class'
 
Zuletzt bearbeitet von einem Moderator:
Zurück