From: Nathan P. <kr...@wa...> - 2007-03-26 13:09:40
|
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: #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; } I then create the following wrapper input file: %Module Testing %include "std_string.i" %include "std_list.i" %{ #include <string> #include <list> #include "Testing.h" %} namespace std { %template (TestingList) std::list<std::string>; } %include "Testing.h" I generate the Perl wrapper and compile the shared object, swig -perl5 -c++ Testing.i g++ -shared -o libTesting.so -I. `perl -MExtUtils::Embed -e ccopts` Testing_wrap.cxx I have the following simple perl script to test it: use Testing; my $test =3D new Testing::Testing; my $list_ret =3D $test->foo_func(); foreach my $e (@$list_ret) { print "$e\n"; } 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. print "$test->{'foo'}\n"; gives: Testing::TestingList=3DHASH(0x81x66ec) 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. my $list =3D Testingc::Testing_foo_get($test); print "$list\n"; 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. %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 */ } 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? 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) =66rom my perl script I could get a proper perl array ref back, and iterate over the list as expected. --=20 Nathan Poznick <kr...@wa...> |