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