From: Bob H. <bh...@co...> - 2014-09-17 23:04:57
|
On 9/17/2014 4:21 PM, Byerley wrote: > %typemap(in) std::list<Cls> { > int size = RARRAY_LEN($input); > std::list<Cls> list; > for (int i = 0; i < size; i++) { > VALUE r_obj = rb_ary_entry($input, i); > Cls *cpp_obj = NULL; > Data_Get_Struct(r_obj, Cls, cpp_obj); > list.push_back(*cpp_obj); > } > $1 = list; > } > > And for the second function, I changed only the first and last part of this > typemap. > Instead of writing > "%typemap(in) std::list<Cls>" and > "$1 = list", > I wrote > "%typemap(in) std::list<Cls> *" and > "$1 = &list". > > I thought this would go fine, but for some reason, it didn't. > When the second function is called, it always shows the first value > correctly, > but the second value is some random value, and then the program is aborted. It's always handy and educational to actually be familiar with the code that SWIG generates. SWIG generates a scope for each typemap instance, so if you look at your SWIG code for the "std::list<Cls> *" version, it will probably become immediately apparent that your "std::list<Cls> list" declaration is only valid within the scope of the typemap code. You are taking a pointer to it ("$1 = &list;") and then it goes out of scope. So, your $1 becomes a dangling pointer. Declare your "list" value as a typemap "temporary" variable, remove the scoped declaration, and you should be much better off: %typemap(in) std::list<Cls> * (std::list<Cls> list) { list.clear(); ... list.push_back(*cpp_obj); ... $1 = &list; } |