Derived Lua objects in C++ containers (with smart pointers)
Glen Fraser <[email protected]> Mon, 8 Jul 2013 13:07:50 +0200
| Newsgroups | gmane.comp.lang.lua.bind.user |
|---|---|
| Message-ID | <[email protected]> |
--===============4172424576004136765==
Content-Type: multipart/alternative;
boundary="Apple-Mail=_B4F6BD3B-D963-459A-A695-3E6DE0EA3186"
--Apple-Mail=_B4F6BD3B-D963-459A-A695-3E6DE0EA3186
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset=us-ascii
Hi there, I've been following section 12.1 of the luabind documentation =
to make Lua classes deriving from a C++ class. I got it all working =
fine, but I still don't understand how to put Lua-created objects into a =
C++ container (STL vector, for example). I'd like to iterate over them =
(in C++) and, calling their overridden (or not) virtual methods. The =
complicating factor (maybe) is that I'd like to use smart pointers in =
the containing STL vector, and I don't see how to use both =
luabind::wrap_base and a smart pointer at the same time, in the class_ =
binding.
(in the below code, assume ofLog() is like cout, and ofPtr is just =
shared_ptr)
C++ code:
class MyItem
{
public:
MyItem(const string &s =3D "MYITEM DEFAULT")
: mStr(s) {
ofLog() << "MyItem::MyItem(" << mStr << ")";
}
=20
virtual void f(int a) {
ofLog() << mStr << " -- MyItem::f(" << a << ")";
}
=20
protected:
string mStr;
};
struct MyItem_wrapper : MyItem, luabind::wrap_base
{
MyItem_wrapper(const string &s)
: MyItem(s) {}
=20
virtual void f(int a) {
call<void>("f", a);
}
=20
static void default_f(MyItem* ptr, int a) {
return ptr->MyItem::f(a);
}
};
class Holder
{
public:
void addItem(ofPtr<MyItem> inItem) {
mObjs.push_back(inItem);
}
void traverse() {
vector<ofPtr<MyItem> >::iterator it;
int num =3D 0;
for (it =3D mObjs.begin(); it !=3D mObjs.end(); it++, num++) {
(*it)->f(num);
}
}
=20
protected:
vector<ofPtr<MyItem> > mObjs;
};
and to register the classes:
module(lua, "objects")
[
class_<Holder>("Holder")
.def(constructor<>())
.def("addItem", &Holder::addItem)
.def("traverse", &Holder::traverse),
=20
class_<MyItem, MyItem_wrapper>("MyItem")
.def(constructor<const string &>())
.def("f", &MyItem::f, &MyItem_wrapper::default_f)
];
Then in Lua, create a derived class and try to add several instances of =
it to the container class:
class 'Derived' (objects.MyItem)
function Derived:__init(str)
objects.MyItem.__init(self, str .. "(Derived)")
self.newParam =3D 1234.5
end
function Derived:f(a)
objects.MyItem.f(self, a)
print(a + 100, self.newParam)
end
hold =3D objects.Holder()
x =3D Derived("hello")
x:f(3)
-- everything works, up to here
hold:addItem(x) -- ka-blooey
x =3D Derived("there")
hold:addItem(x)
hold:traverse()
On the first addItem(), I get the following error:
got an error: Runtime error: No matching overload found, candidates:
void addItem(Holder&,custom [5ofPtrI6MyItemE])
Any tips on how to do what I'm trying to do? Do I have to make a new =
wrapper class that's a combination of luabind::wrap_base and shared_ptr? =
I can skip using smart pointers for the container, if someone can =
explain how I should manage object lifetime, when the "Holder" container =
may have a mixture of Lua-created and C++-created objects.
Thanks,
Glen.
--Apple-Mail=_B4F6BD3B-D963-459A-A695-3E6DE0EA3186
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
charset=us-ascii
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html =
charset=3Dus-ascii"></head><body style=3D"word-wrap: break-word; =
-webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Hi =
there, I've been following section 12.1 of the luabind documentation to =
make Lua classes deriving from a C++ class. I got it all working =
fine, but I still don't understand how to put Lua-created objects into a =
C++ container (STL vector, for example). I'd like to iterate over =
them (in C++) and, calling their overridden (or not) virtual methods. =
The complicating factor (maybe) is that I'd like to use smart =
pointers in the containing STL vector, and I don't see how to use both =
luabind::wrap_base and a smart pointer at the same time, in the class_ =
binding.<div><br></div><div>(in the below code, assume ofLog() is like =
cout, and ofPtr is just shared_ptr)<br><div><br></div><div>C++ =
code:</div><div><br></div><div><div style=3D"margin: 0px; font-size: =
12px; font-family: Menlo; "><div style=3D"margin: 0px; "><span =
style=3D"color: #bb2ca2">class</span> MyItem</div><div style=3D"margin: =
0px; ">{</div><div style=3D"margin: 0px; color: rgb(187, 44, 162); =
">public<span style=3D"color: #000000">:</span></div><div style=3D"margin:=
0px; "> MyItem(<span style=3D"color: #bb2ca2">const</span> =
<span style=3D"color: #703daa">string</span> &s =3D <span =
style=3D"color: #d12f1b">"MYITEM DEFAULT"</span>)</div><div =
style=3D"margin: 0px; "> : <span style=3D"color: =
#4f8187">mStr</span>(s) {</div><div style=3D"margin: 0px; "> =
<span style=3D"color: #4f8187">ofLog</span>() =
<< <span style=3D"color: #d12f1b">"MyItem::MyItem("</span> =
<< <span style=3D"color: #4f8187">mStr</span> << <span =
style=3D"color: #d12f1b">")"</span>;</div><div style=3D"margin: 0px; =
"> }</div><p style=3D"margin: 0px; min-height: 14px; =
"> <br class=3D"webkit-block-placeholder"></p><div =
style=3D"margin: 0px; color: rgb(187, 44, 162); "><span style=3D"color: =
#000000"> </span>virtual<span style=3D"color: #000000"> =
</span>void<span style=3D"color: #000000"> f(</span>int<span =
style=3D"color: #000000"> a) </span>{</div><div style=3D"margin: =
0px; "> <span style=3D"color: =
#4f8187">ofLog</span>() << <span style=3D"color: =
#4f8187">mStr</span> << <span style=3D"color: #d12f1b">" -- =
MyItem::f("</span> << a << <span style=3D"color: =
#d12f1b">")"</span>;</div><div style=3D"margin: 0px; "> =
}</div><p style=3D"margin: 0px; min-height: 14px; "> =
<br class=3D"webkit-block-placeholder"></p><div style=3D"margin: =
0px; color: rgb(187, 44, 162); ">protected<span style=3D"color: =
#000000">:</span></div><div style=3D"margin: 0px; "> <span =
style=3D"color: #703daa">string</span> mStr;</div><div =
style=3D"margin: 0px; ">};</div><div style=3D"margin: 0px; min-height: =
14px; "><br></div><div style=3D"margin: 0px; "><span style=3D"color: =
#bb2ca2">struct</span> MyItem_wrapper : <span style=3D"color: =
#4f8187">MyItem</span>, <span style=3D"color: =
#4f8187">luabind</span>::<span style=3D"color: =
#4f8187">wrap_base</span></div><div style=3D"margin: 0px; ">{</div><div =
style=3D"margin: 0px; "> MyItem_wrapper(<span style=3D"color:=
#bb2ca2">const</span> <span style=3D"color: #703daa">string</span> =
&s)</div><div style=3D"margin: 0px; "> : <span =
style=3D"color: #4f8187">MyItem</span>(s) {}</div><p style=3D"margin:=
0px; min-height: 14px; "> <br =
class=3D"webkit-block-placeholder"></p><div style=3D"margin: 0px; color: =
rgb(187, 44, 162); "><span style=3D"color: #000000"> =
</span>virtual<span style=3D"color: #000000"> </span>void<span =
style=3D"color: #000000"> f(</span>int<span style=3D"color: #000000"> =
a) </span>{</div><div style=3D"margin: 0px; "> =
<span style=3D"color: #31595d">call</span><<span style=3D"color:=
#bb2ca2">void</span>>(<span style=3D"color: #d12f1b">"f"</span>, =
a);</div><div style=3D"margin: 0px; "> }</div><p =
style=3D"margin: 0px; min-height: 14px; "> <br =
class=3D"webkit-block-placeholder"></p><div style=3D"margin: 0px; =
"> <span style=3D"color: #bb2ca2">static</span> <span =
style=3D"color: #bb2ca2">void</span> default_f(<span style=3D"color: =
#4f8187">MyItem</span>* ptr, <span style=3D"color: #bb2ca2">int</span> =
a) {</div><div style=3D"margin: 0px; "> =
<span style=3D"color: #bb2ca2">return</span> ptr-><span style=3D"color:=
#4f8187">MyItem</span>::<span style=3D"color: =
#31595d">f</span>(a);</div><div style=3D"margin: 0px; "> =
}</div><div style=3D"margin: 0px; ">};</div><div style=3D"margin: 0px; =
"><br></div><div style=3D"margin: 0px; "><span style=3D"color: rgb(187, =
44, 162); ">class</span> Holder</div><div style=3D"margin: 0px; "><div =
style=3D"margin: 0px; ">{</div><div style=3D"margin: 0px; color: =
rgb(187, 44, 162); ">public<span style=3D"color: =
#000000">:</span></div><div style=3D"margin: 0px; color: rgb(0, 132, 0); =
"> <span style=3D"color: rgb(187, 44, 162); =
">void</span> addItem(<span style=3D"color: rgb(79, 129, 135); =
">ofPtr</span><<span style=3D"color: rgb(79, 129, 135); =
">MyItem</span>> inItem) {</div><div style=3D"margin: 0px; "> =
<span style=3D"color: #4f8187">mObjs</span>.<span =
style=3D"color: #3d1d81">push_back</span>(inItem);</div><div =
style=3D"margin: 0px; "> }</div><div style=3D"margin: 0px; =
min-height: 14px; "><br></div><div style=3D"margin: 0px; "> =
<span style=3D"color: #bb2ca2">void</span> traverse() {</div><div =
style=3D"margin: 0px; color: rgb(0, 132, 0); "> =
<span style=3D"color: rgb(112, 61, 170); =
">vector</span><<span style=3D"color: rgb(79, 129, 135); =
">ofPtr</span><<span style=3D"color: rgb(79, 129, 135); =
">MyItem</span>> >::<span style=3D"color: rgb(112, 61, 170); =
">iterator</span> it;</div><div style=3D"margin: 0px; =
"> <span style=3D"color: #bb2ca2">int</span> =
num =3D <span style=3D"color: #272ad8">0</span>;</div><div =
style=3D"margin: 0px; "> <span style=3D"color: =
#bb2ca2">for</span> (it =3D <span style=3D"color: =
#4f8187">mObjs</span>.<span style=3D"color: #3d1d81">begin</span>(); it =
!=3D <span style=3D"color: #4f8187">mObjs</span>.<span style=3D"color: =
#3d1d81">end</span>(); it++, num++) {</div><div style=3D"margin: 0px; =
"> (*it)-><span =
style=3D"color: #31595d">f</span>(num);</div><div style=3D"margin: 0px; =
"> }</div><div style=3D"margin: 0px; "> =
}</div><p style=3D"margin: 0px; min-height: 14px; "> =
<br class=3D"webkit-block-placeholder"></p><div style=3D"margin: =
0px; color: rgb(187, 44, 162); ">protected<span style=3D"color: =
#000000">:</span></div><div style=3D"margin: 0px; "> <span =
style=3D"color: #703daa">vector</span><<span style=3D"color: =
#4f8187">ofPtr</span><<span style=3D"color: =
#4f8187">MyItem</span>> > mObjs;</div><div =
style=3D"margin: 0px; color: rgb(0, 132, 0); ">};</div></div><div =
style=3D"margin: 0px; "><br></div></div></div><div>and to register the =
classes:</div><div><br></div><div><div style=3D"margin: 0px; font-size: =
12px; font-family: Menlo; "> =
<span style=3D"color: #31595d">module</span>(<span =
style=3D"color: #31595d">lua</span>, <span style=3D"color: =
#d12f1b">"objects"</span>)</div><div style=3D"margin: 0px; font-size: =
12px; font-family: Menlo; "> =
[</div><div style=3D"margin: 0px; font-size: 12px; font-family: Menlo; =
"> <span style=3D"color: =
#31595d">class_</span><<span style=3D"color: =
#31595d">Holder</span>>(<span style=3D"color: =
#d12f1b">"Holder"</span>)</div><div style=3D"margin: 0px; font-size: =
12px; font-family: Menlo; "> =
.<span style=3D"color: #31595d">def</span>(<span style=3D"color: =
#31595d">constructor</span><>())</div><div style=3D"margin: 0px; =
font-size: 12px; font-family: Menlo; "> =
.<span style=3D"color: #31595d">def</span>(<span =
style=3D"color: #d12f1b">"addItem"</span>, &<span style=3D"color: =
#31595d">Holder</span>::<span style=3D"color: =
#31595d">addItem</span>)</div><div style=3D"margin: 0px; font-size: =
12px; font-family: Menlo; "> =
.<span style=3D"color: #31595d">def</span>(<span style=3D"color: =
#d12f1b">"traverse"</span>, &<span style=3D"color: =
#31595d">Holder</span>::<span style=3D"color: =
#31595d">traverse</span>),</div><p style=3D"margin: 0px; font-size: =
12px; font-family: Menlo; min-height: 14px; "> =
<br class=3D"webkit-block-placeholder"></p><div=
style=3D"margin: 0px; font-size: 12px; font-family: Menlo; "> =
<span style=3D"color: rgb(49, =
89, 93); ">class_</span><<span style=3D"color: rgb(49, 89, 93); =
">MyItem</span>, <span style=3D"color: rgb(49, 89, 93); =
">MyItem_wrapper</span>>(<span style=3D"color: rgb(209, 47, 27); =
">"MyItem"</span>)</div><div style=3D"margin: 0px; font-size: 12px; =
font-family: Menlo; color: rgb(0, 132, 0); "> =
.<span style=3D"color: rgb(49, 89, 93); =
">def</span>(<span style=3D"color: rgb(49, 89, 93); =
">constructor</span><<span style=3D"color: rgb(187, 44, 162); =
">const</span> <span style=3D"color: rgb(49, 89, 93); ">string</span> =
&>())</div><div style=3D"margin: 0px; font-size: 12px; =
font-family: Menlo; color: rgb(49, 89, 93); "><span style=3D"color: =
#000000"> =
.</span>def<span style=3D"color: #000000">(</span><span style=3D"color: =
#d12f1b">"f"</span><span style=3D"color: #000000">, =
&</span>MyItem<span style=3D"color: #000000">::</span>f<span =
style=3D"color: #000000">, &</span>MyItem_wrapper<span style=3D"color:=
#000000">::</span>default_f<span style=3D"color: =
#000000">)</span></div><div style=3D"margin: 0px; font-size: 12px; =
font-family: Menlo; "> =
];</div><p style=3D"margin: 0px; font-size: 12px; font-family: Menlo; =
min-height: 14px; "><br></p><p style=3D"margin: 0px; font-size: 12px; =
font-family: Menlo; min-height: 14px; "><br></p><p style=3D"margin: 0px; =
min-height: 14px; ">Then in Lua, create a derived class and try to add =
several instances of it to the container class:</p><p style=3D"margin: =
0px; font-size: 12px; font-family: Menlo; min-height: 14px; "><br></p><p =
style=3D"margin: 0px; font-size: 12px; min-height: 14px; "><div =
style=3D"margin: 0px; "><div style=3D"font-family: Menlo; margin: 0px; =
">class 'Derived' (objects.MyItem)</div><div style=3D"font-family: =
Menlo; margin: 0px; min-height: 14px; "><br></div><div =
style=3D"font-family: Menlo; margin: 0px; ">function =
Derived:__init(str)</div><div style=3D"font-family: Menlo; margin: 0px; =
"> objects.MyItem.__init(self, str .. =
"(Derived)")</div><div style=3D"font-family: Menlo; margin: 0px; =
"> self.newParam =3D 1234.5</div><div style=3D"font-family: =
Menlo; margin: 0px; ">end</div><div style=3D"font-family: Menlo; margin: =
0px; min-height: 14px; "><br></div><div style=3D"font-family: Menlo; =
margin: 0px; ">function Derived:f(a)</div><div style=3D"font-family: =
Menlo; margin: 0px; "> objects.MyItem.f(self, a)</div><div =
style=3D"font-family: Menlo; margin: 0px; "> print(a + 100, =
self.newParam)</div><div style=3D"font-family: Menlo; margin: 0px; =
">end</div><div style=3D"font-family: Menlo; "><br></div><div =
style=3D"font-family: Menlo; "><div style=3D"margin: 0px; ">hold =3D =
objects.Holder()</div><div style=3D"margin: 0px; ">x =3D =
Derived("hello")</div><div style=3D"margin: 0px; ">x:f(3)</div><div =
style=3D"margin: 0px; ">-- everything works, up to here</div><div =
style=3D"margin: 0px; "><br></div><div style=3D"margin: 0px; =
">hold:addItem(x) -- ka-blooey</div><div style=3D"margin: 0px; =
">x =3D Derived("there")</div><div style=3D"margin: 0px; =
">hold:addItem(x)</div><div style=3D"margin: 0px; =
">hold:traverse()</div></div><div style=3D"font-family: Menlo; =
"><br></div><div>On the first addItem(), I get the following =
error:</div></div></p><div><br></div></div></div><div><div =
style=3D"margin: 0px; font-size: 11px; font-family: Menlo; "><b>got an =
error: Runtime error: No matching overload found, =
candidates:</b></div><div style=3D"margin: 0px; font-size: 11px; =
font-family: Menlo; "><b>void addItem(Holder&,custom =
[5ofPtrI6MyItemE])</b></div></div><div style=3D"margin: 0px; font-size: =
11px; font-family: Menlo; "><br></div><div style=3D"margin: 0px; =
font-size: 11px; font-family: Menlo; "><div style=3D"margin: 0px; =
"><span style=3D"font-family: Helvetica; font-size: 12px; ">Any tips on =
how to do what I'm trying to do? Do I have to make a new wrapper =
class that's a combination of luabind::wrap_base and shared_ptr? I =
can skip using smart pointers for the container, if someone can explain =
how I should manage object lifetime, when the "Holder" container may =
have a mixture of Lua-created and C++-created objects.</span></div><div =
style=3D"margin: 0px; "><br></div><div style=3D"margin: 0px; "><span =
style=3D"font-family: Helvetica; font-size: 12px; =
">Thanks,</span></div><div style=3D"margin: 0px; "><span =
style=3D"font-family: Helvetica; font-size: 12px; =
">Glen.</span></div><div style=3D"margin: 0px; "><span =
style=3D"font-family: Helvetica; font-size: 12px; =
"><br></span></div></div></body></html>=
--Apple-Mail=_B4F6BD3B-D963-459A-A695-3E6DE0EA3186--
--===============4172424576004136765==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:
Build for Windows Store.
http://p.sf.net/sfu/windows-dev2dev
--===============4172424576004136765==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
_______________________________________________
luabind-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/luabind-user
--===============4172424576004136765==--