From: Nathan P. <kr...@wa...> - 2007-04-04 06:00:41
|
Any comments or suggestions on this? Thus spake Nathan Poznick: > I've got a situation where I want to wrap a C++ class which has member > variables. The target language is Perl, although I don't know if my > issue is specific to it. For discussion purposes, I have the following > class defined: >=20 > #include <string> > #include <list> > class Testing { > public: > Testing(); > ~Testing(); > std::list<std::string> foo_func(); > std::list<std::string> foo; > }; > Testing::Testing() { > foo.push_back("list entry 1"); > foo.push_back("list entry 2"); > } > Testing::~Testing() { } > Testing::foo_func() { > return this->foo; > } >=20 > I then create the following wrapper input file: >=20 > %Module Testing >=20 > %include "std_string.i" > %include "std_list.i" >=20 > %{ > #include <string> > #include <list> > #include "Testing.h" > %} >=20 > namespace std { > %template (TestingList) std::list<std::string>; > } >=20 > %include "Testing.h" >=20 > I generate the Perl wrapper and compile the shared object, >=20 > swig -perl5 -c++ Testing.i > g++ -shared -o libTesting.so -I. `perl -MExtUtils::Embed -e ccopts` > Testing_wrap.cxx >=20 > I have the following simple perl script to test it: >=20 > use Testing; > my $test =3D new Testing::Testing; > my $list_ret =3D $test->foo_func(); > foreach my $e (@$list_ret) { > print "$e\n"; > } >=20 > So far, so good. When returning a std::list from a class method, it > properly gets turned into a Perl array ref, and I can access the > results. However, if I try to access the member variable directly, I > run into problems. Printing it out directly indicates that it's being > treated as a TestingList perl object. >=20 > print "$test->{'foo'}\n"; >=20 > gives: >=20 > Testing::TestingList=3DHASH(0x81x66ec) >=20 > Well, I can understand that. The object is basically useless to me > though, unless there's something I'm missing - it only has size(), > empty(), clear(), and push() methods - no way to actually access the > contents. I thought perhaps I could use the auto-generated _get method > to grab it instead, thinking it would perhaps to the conversion the same > way as when the list is returned from a method. >=20 > my $list =3D Testingc::Testing_foo_get($test); > print "$list\n"; >=20 > But nope, that gives me the same thing as accessing it directly. From > there I thought that perhaps I needed to define some typemaps for the > list. >=20 > %typemap(out) std::list<std::string> { > /* Perlguts voodoo to convert a list of > strings to an array goes here */ > } > %typemap(memberin) std::list<std::string> { > /* Perlguts voodoo to convert an array to > a list of strings goes here */ > } >=20 > Yet, I ran into a problem - when I look at the generated > Testing_wrap.cxx file, the typemap I define for out gets inserted into > _wrap_Testing_foo_func() (which was working fine before, I just stole > the code from it to insert into the typemap). The memberin typemap gets > inserted into _wrap_Testing_foo_set() as you would expect. Yet, I'm > left with _wrap_Testing_foo_get() *not* using the out typemap. If I can > affect the _set() method using the memberin typemap, but not affect the > _get() method with an out typemap, how do I accomplish what I need to > do? >=20 > I did some quick testing and manually inserted my output typemap into > the generated _wrap_Testing_foo_get() function, and after compilation it > worked as I would expect - by calling Testingc::Testing_foo_get($test) > from my perl script I could get a proper perl array ref back, and > iterate over the list as expected. --=20 Nathan Poznick <kr...@wa...> |