Home › Forums › General › Programming › Pass StringArray back to C++
- This topic has 10 replies, 2 voices, and was last updated 9 years, 6 months ago by atom.
-
AuthorPosts
-
September 17, 2014 at 10:34 am #29139
Hi I am trying to pass a StringArray which I created in Lua back to C++ :
Here is my Lua code:
>>> myarray = StringArray() myarray:set(0, String("str2")) myarray:set(1, String("str3")) i=obj:callback(myarray) ERROR: No matching overload found
My C++ code is like :
bool callback(StringArray& arr) {….}Is it at all possible to pass arrays from Lua to C++ , or C++ to Lua ?
September 17, 2014 at 12:10 pm #29142It should be if you registered StringArray() (if you are using all the Ctrlr stuff it should be there)
How are you registering you class with the “callback” callback, since it looks like it’s finding the wrong overloaded method.
You can always use the what() and how() functions to see what methods are registered for a class.
September 17, 2014 at 2:31 pm #29145Well I checked the declaration of the C++ function again and it seems I need to make it as :
bool callback(const StringArray& arr) {….}
Now I am able to receive String arrays sent from Lua into C++.
Lets say I want to send a StringArray from C++ to Lua. Thats where I am stuck now:
If I have a C++ function like :const StringArray& callback(<strong>const </strong>StringArray& arr) { return m_saTest; }
This returns a StringArray to Lua. But am not able to read this StringArray in Lua:
sa = callback(testArray);
console(String(sa:get(1)))Error !!
September 17, 2014 at 3:45 pm #29152You should not return references from callbacks. The object lifetime with luabind is very complicated, you have to look at policies and how they work.
I’d just do const StringArray callback(const StringArray parameter) and bind that to luabind. I tested my StringArray stuff and it works, if you are getting problems, you need to show me all the code, the c++ part where you bind the class and the lua part that causes errors, and i ‘ll try to help.
September 17, 2014 at 3:52 pm #29153I think I understand whats happening here.
The JUCE StringArray class allows access to its data through overloading the [] operator. It does not provide a StringArray::get() , so you have provided one via LStringArray::get() in LString.cpp
class_<StringArray, LStringArray>("StringArray") .def(constructor<>()) .def(constructor<const String &>()) .def(constructor<const char *const *, const int>()) .def(constructor<const char *const *>()) .def("size", &StringArray::size) .def("get", &LStringArray::get) .def("contains", &StringArray::contains) ....
Thats fine. But if I were to return a StringArray from a C++ function :
const StringArray& testArray(const StringArray& arr);Its not recognized in lua.
So I solved it by exposing StringArray::operator[] in LString.cpp :
class_<StringArray, LStringArray>("StringArray") .def(constructor<>()) .def(constructor<const String &>()) .def(constructor<const char *const *, const int>()) .def(constructor<const char *const *>()) .def("size", &StringArray::size) .def("getAt", &StringArray::operator[]) <----------- .def("get", &LStringArray::get) .def("contains", &StringArray::contains)
September 17, 2014 at 3:53 pm #29154oh wait, I did not see your reply, reading it now 🙂
————–
ok, you are right I should not be passing back references from C++ into Lua. If the object is destroyed in the C++ side by any chance, then lua might still have that reference and cause a crash if its used in lua code.
So yeah I ll try now with :
StringArray callback(void) {….}- This reply was modified 9 years, 6 months ago by synth.
September 17, 2014 at 4:03 pm #29157ok, so I have tried. The problem is that when I return a StringArray from C++(not a StringArray & ), then it does get created in the lua side as expected. But I cant read its values using :
sa = obj:callback() val = sa:get(0) ERROR: No matching overload found, candidates: String get(custom [class LStringArray]&,int)
If you have a function in C++ side that returns a StringArray then are you able to read out the values in the StringArray using get() after you call the function ?
- This reply was modified 9 years, 6 months ago by synth.
September 17, 2014 at 5:36 pm #29161Yeah you are correct this won’t work because you need to return LStringArray in your C++ callback() so that types match, i’ll try to fix that, so that you can return StringArray and LStringArray in c++.
An additional constructor:
LStringArray(const StringArray &other) : StringArray(other) {}will be needed in LStringArray() to get this working i don’t know why i missed that.
September 17, 2014 at 5:39 pm #29162Yeah and i changed how StringArray is bound to lua:
class_<LStringArray>("LStringArray") , class_<StringArray, bases<LStringArray> >("StringArray") .def(constructor<>()) .def(constructor<const String &>()) .def(constructor<const char *const *, const int>()) .def(constructor<const char *const *>()) .def(constructor<const StringArray &>())
this should help
September 19, 2014 at 10:36 am #29221Thanks it works now. Do you know if we can pass native arrays back end forth.
Like if we have a C++ function which returns an array of doubles :
double[] doTask(void)
Can we call this in Lua and receive the array ? Or do we need to put the doubles in a StringArray and return that ?
September 19, 2014 at 11:38 am #29231Well you can’t do it like that, but you can pass luabind::object objects and those can wrap aroung lua tables, you’d need to convert between them but it’s really simple, for example to convert to a float Array (this is in CtrlrInlineUtilities.h)
static inline Array<float> luaArrayToFloat(const luabind::object &luaArray) { Array<float> data; if (luaArray.is_valid() && luabind::type(luaArray) == LUA_TTABLE) { for(luabind::iterator i(luaArray), end; i != end; i++) { data.add (luabind::object_cast<float>(*i)); } } return (data); }
-
AuthorPosts
- The forum ‘Programming’ is closed to new topics and replies.