Perl Swig におけるSTLのvector/string typemap
Google Cacheからお宝発見。http://72.14.207.104/search?q=cache:-HxRbJf6tigJ:mailman.cs.uchicago.edu/pipermail/swig/2002-August/005367.html+typemap+perl+swig+array+char&hl=ja&gl=jp&ct=clnk&cd=4
PerlのSwigとC++のSTL(vector, string)のtypemap。
追記:
Perl側から arrayリファレンスを渡して、vector
同じく、vector
ただし vector_tempがないとか言われるので適当にごにょる。
スマートな解決方法をご存知の方ぜひつっこみをお願いします。
いつなくなるか分からないので全文引用しておきます。
Chris Seatory chriss@regasia.com Mon, 5 Aug 2002 13:35:21 +1000 * Previous message: [Swig] Inserting #includes before the rest of the wrapper code (again) * Next message: [Swig] C++ / Perl STL mappings * Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] Hi, After a few recent clues from David Beasley and Brett H. Williams, I've now fixed all memory leaks in my Perl 5 <-> C++ mappings. Below, you will find my typemaps for: perl5 string <-> c++ std::string perl5 string <-> c++ std::string pointer or reference perl5 array ref <-> c++ std::vector<std::string> perl5 array ref <-> c++ std::vector<std::string> pointer or reference perl5 array ref <-> c++ std::vector<OBJECT> perl5 array ref <-> c++ std::vector<OBJECT> pointer or reference Simply copy the code below into "perl5-stl.i", and %include it in your interface file. To add support for each vector, in your interface file specify: VECTORIN(MyObject) VECTOROUT(MyObject) I am keen to contribute to SWIG's C++ STL support for Perl. If you'd like my help, please let me know where to start. Cheers, Chris Seatory Programmer AusRegistry Pty Ltd Melbourne, Australia /* SWIG PERL5/C++ typemaps for C++ STL strings and vectors refer to "perlguts" man page and SWIG manual Author: Chris Seatory <chriss@regasia.com> Version: $Id: perl5-stl.i,v 1.2 2002/08/05 03:12:42 chriss Exp $ */ /* INPUT ARGUMENT TYPE MAPPINGS */ // Perl5 string // C++ pointer or reference to STL string %typemap(in) std::string*, std::string& ($basetype string_temp) { if (!SvPOK($input)) croak("Argument $argnum is not a string"); STRLEN len; char *ptr = SvPV($input, len); string_temp.assign(ptr, len); $1 = &string_temp; argvi++; } // Perl5 string // C++ STL string %typemap(in) std::string { if (!SvPOK($input)) croak("Argument $argnum is not a string"); STRLEN len; char *ptr = SvPV($input, len); $1 = std::string(ptr, len); argvi++; } // Perl5 reference to array of strings // C++ pointer or reference to STL vector of STL strings %typemap(in) std::vector<std::string>*, std::vector<std::string>& ($basetype vec tor_temp) { if (!SvROK($input)) croak("$input is not a reference."); AV *av = (AV *)SvRV($input); if (SvTYPE(av) != SVt_PVAV) croak("$input is not an array."); SV **tv; I32 l = av_len(av) + 1; STRLEN len; for (int i = 0; i < l; i++) { tv = av_fetch(av, i, 0); std::string str = std::string(SvPV(*tv, len)); vector_temp.push_back(str); } $1 = &vector_temp; argvi++; } %define VECTORIN(OBJECT) // Perl5 reference to array of arbitrary objects // C++ pointer or reference to STL vector of objects %typemap(in) std::vector<OBJECT>*, std::vector<OBJECT>& ($basetype vector_temp) { if (!SvROK($input)) croak("$input is not a reference."); AV *av = (AV *)SvRV($input); if (SvTYPE(av) != SVt_PVAV) croak("$input is not an array."); SV **tv; I32 len = av_len(av) + 1; OBJECT *obj; swig_type_info *ti = SWIG_TypeQuery("OBJECT"); int i; for (i = 0; i < len; i++) { tv = av_fetch(av, i, 0); SWIG_ConvertPtr(*tv, (void **)&obj, ti, 0); vector_temp.push_back(*obj); } $1 = &vector_temp; argvi++; } %enddef /* OUTPUT ARGUMENT TYPE MAPPINGS */ // C++ pointer or reference to STL string // Perl5 string %typemap(out) std::string*, std::string& { $result = sv_newmortal(); sv_setpvn($result, ($1)->data(), ($1)->size()); argvi++; } // C++ STL string // Perl5 string %typemap(out) std::string { $result = sv_newmortal(); sv_setpvn($result, ($1).data(), ($1).size()); argvi++; } // C++ pointer or reference to STL vector of STL strings // Perl5 reference to array of strings %typemap(out) std::vector<std::string>*, std::vector<std::string>& { int len = ($1)->size(); SV **svs = new SV*[len]; for (int x = 0; x < len; x++) { SV* sv = sv_newmortal(); sv_setpvn(sv, $1->at(x).data(), $1->at(x).size()); svs[x] = sv; } AV *myav = av_make(len, svs); delete[] svs; $result = newRV_noinc((SV*) myav); sv_2mortal($result); argvi++; } // C++ STL vector of STL strings // Perl5 reference to array of strings %typemap(out) std::vector<std::string> { int len = $1.size(); SV **svs = new SV*[len]; for (int x = 0; x < len; x++) { SV* sv = sv_newmortal(); sv_setpvn(sv, $1[x].data(), $1[x].size()); svs[x] = sv; } AV *myav = av_make(len, svs); delete[] svs; $result = newRV_noinc((SV*) myav); sv_2mortal($result); argvi++; } %define VECTOROUT(OBJECT) // C++ pointer or reference to STL vector of arbitrary objects // Perl5 reference to array of arbitrary objects %typemap(out) std::vector<OBJECT>*, std::vector<OBJECT>& { int len = $1->size(); SV **svs = new SV*[len]; for (int x = 0; x < len; x++) { svs[x] = sv_newmortal(); SWIG_MakePtr(svs[x], (void*)&($1->at(x)), SWIGTYPE_p_ ## OBJECT, 0); } AV *myav = av_make(len, svs); delete[] svs; $result = newRV_noinc((SV*) myav); sv_2mortal($result); argvi++; } // C++ STL vector of arbitrary objects // Perl5 reference to array of arbitrary objects %typemap(out) std::vector<OBJECT> { int len = $1.size(); SV **svs = new SV*[len]; for (int x = 0; x < len; x++) { svs[x] = sv_newmortal(); SWIG_MakePtr(svs[x], (void*)&($1[x]), SWIGTYPE_p_ ## OBJECT, 0); } AV *myav = av_make(len, svs); delete[] svs; $result = newRV_noinc((SV*) myav); sv_2mortal($result); argvi++; } %enddef