tags:

views:

369

answers:

2

I want to access a template List of C++ program from a Perl script and use those values.

Example code:

typedef list < Struct1  * > sturct1_list;

struct Struct2
{
    int i;
    struct1_list List1;
}

struct Struct1
{
    int j;
}

I used one swig generated api and did the following:

$myList = Struct2_struct1List_get 
print "Reference type: " . ref($myList) ;

now this prints as:

Reference type:  \_p\_std\_\_listTutils\_\_Struct1\_p\_t

how to get the values from the structure using this?

Update from duplicate question:

in interface file i put

%template(ListStruct1) std::list< Struct1 * >;

after i generate the ".pm" file. I checked the APIs available this list.

I found

ListStuct1_size
ListStuct1_empty
ListStuct1_clear
ListStuct1_push.

I was able to use those elements. But i dont know how to access individual elements of the list using these API? or am I missing something in interface file?

UPDATED:

Is typemap possible to return the list as array here??

+3  A: 

First of all, general info

This tutorial shows how to do the wrapper for templates.

The same tutorial shows how to use the module from Perl, but the perl example doesn't touch templates.

This SO article shows how to do that with a Vector

Here's a general SWIG STL documentation that seems to mention *std_list.i* interface.

Second, regarding lists

  1. You can not "access" C++ list like a Perl array, by a subscript. If you wanted that, you must use a Vector as underlying type.

  2. As an alternate, create a class extending List, give it a new method which returns an element by an index, and expose that method in an interface.

  3. If you wish to access the list by finding an element, like in C++, you need to write a List interface that exposes find() method - the default one does not from reading the source code.

DVK
hi.. i read the documetation.. but i still confused how will access that list from perl?
Anandan
You can't "access" the data in a list from perl since the default list interface doesn't expose any way for you to do so. See my updates in the answer for 3 possible solutions, depending on what you need.
DVK
can we do %typemap(out) list<Struct1 *> {} and return it as an array??
Anandan
You probably can, but I'm not quite sure of the purpose of having a list in C++ side (as opposed to the vector) if you merely turn it into vector-like Perl array?
DVK
+1  A: 

In your interface, try:

%include "std_list.i"

%template(ListStruct1) std::list< Struct1 * >;

The std library is kinda funny, there's no actual binary object called list that swig can just wrap, it's all templates - so swig needs some extra help to figure out what's going on.

That should add insert, remove, and a bunch of other list specific functions to the wrapper.

If the above doesn't work, try adding:

%define SWIG_EXPORT_ITERATOR_METHODS

UPDATE: Of course, I neglected to mention (or even realize) that this works great for python, java, and a few others, but is totally broken in perl...

jmanning2k
Without a std_list.i supporting perl, you're limited to size, empty, clear, push. I tested with swig 1.3.39. Vector, however, gives push, pop, get, set - which might actually be useful.
jmanning2k
thanks for the reply.. i have not tried the %define directive that specified.. but i want that to work in perl.. anyways I will just try that out..
Anandan