Pass StringArray back to C++

Home Forums General Programming Pass StringArray back to C++

Viewing 11 posts - 1 through 11 (of 11 total)
  • Author
    Posts
  • #29139
    synth
    Participant
      • Topics: 13
      • Replies: 35
      • Total: 48

      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 ?

      #29142
      atom
      Keymaster
        • Topics: 159
        • Replies: 2945
        • Total: 3104
        • ★★★★★

        It 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.

        #29145
        synth
        Participant
          • Topics: 13
          • Replies: 35
          • Total: 48

          Well 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 !!

          #29152
          atom
          Keymaster
            • Topics: 159
            • Replies: 2945
            • Total: 3104
            • ★★★★★

            You 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.

            #29153
            synth
            Participant
              • Topics: 13
              • Replies: 35
              • Total: 48

              I 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)
              #29154
              synth
              Participant
                • Topics: 13
                • Replies: 35
                • Total: 48

                oh 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.
                #29157
                synth
                Participant
                  • Topics: 13
                  • Replies: 35
                  • Total: 48

                  ok, 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.
                  #29161
                  atom
                  Keymaster
                    • Topics: 159
                    • Replies: 2945
                    • Total: 3104
                    • ★★★★★

                    Yeah 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.

                    #29162
                    atom
                    Keymaster
                      • Topics: 159
                      • Replies: 2945
                      • Total: 3104
                      • ★★★★★

                      Yeah 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

                      #29221
                      synth
                      Participant
                        • Topics: 13
                        • Replies: 35
                        • Total: 48

                        Thanks 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 ?

                        #29231
                        atom
                        Keymaster
                          • Topics: 159
                          • Replies: 2945
                          • Total: 3104
                          • ★★★★★

                          Well 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);
                          }
                        Viewing 11 posts - 1 through 11 (of 11 total)
                        • The forum ‘Programming’ is closed to new topics and replies.
                        There is currently 0 users and 50 guests online
                        No users are currently active
                        Forum Statistics
                        Threads: 2,495, Posts: 17,374, Members: 77,605
                        Most users ever online was 12 on January 22, 2019 3:47 pm
                        Ctrlr