2

I am pretty new to SWIG and this is my first application in which I'm trying to make a generic List which is coded in C++ and trying to extend it in Python using SWIG
Code in list.h is as follows

 #include <bits/stdc++.h>

template <typename T>
class List
{
    public:
        T* data;
        int max_items;
        int n_items;
        List(int max);
        void append(T d);
        T get(int index);
};

typedef List<int> IntList;
typedef List<float> FloatList;

Code in list.cpp is as follows

#include "list.h"

template <class T> List<T>::List(int max) {
    max_items = max;
    data = new T[max_items];
    n_items = 0;
}

template <class T> void List<T>::append(T d) {
    if(n_items < max_items)
        data[n_items++] = d;
}

template <class T> T List<T>::get(int index) {
    return data[index];
}

And the SWIG input interface file list.i has following code

%module list_swig

%{
        #include "list.h"
%}

template <class T>
class List {
        public:
            T* data;
            int max_items;
            int n_items;
            List(int max);
            void append(T data);
            T get(int index);
};

template <class T> List<T>::List(int max) {
    max_items = max;
    data = new T[max_items];
    n_items = 0;
}

template <class T> void List<T>::append(T d) {
    if(n_items < max_items)
        data[n_items++] = d
}

template <class T> T List<T>::get(int index) {
    return data[index];
}


%template(IntPoint) List <int>;
%template(FloatPoint) List <float>;

I'm compiling as follows

swig -c++ -python -o list_wrap.cpp list.i
g++ -c -fPIC list.cpp
g++ -c -fPIC list_wrap.cpp -I/usr/include/python2.7
g++ -shared -o _list_swig.so list.o list_wrap.o

Every step produced output without any error but when I'm trying to import the file in python shell, it gives me following error

./_list_swig.so: undefined symbol: _ZN4ListIfE6appendE

Can anybody explain why this error occurred? Or where I'm making mistakes?
Thanks in advance!

Edit: The link to all the codes is https://github.com/b282022/SWIG-Experiment

  • **Recommended reading: "[Why should I not #include ?](http://stackoverflow.com/q/31816095/560648)"** – Lightness Races in Orbit May 15 '17 at 12:20
  • **Recommended reading: "[Why can templates only be implemented in the header file?](http://stackoverflow.com/q/495021/560648)"** – Lightness Races in Orbit May 15 '17 at 12:22
  • Thank you @BoundaryImposition, Your readings has helped very much and now all the code works just fine. My only doubt is, if I have a big library to be extended in Python then do I need to have all definitions of templated class in .h files or is there any other work around? – Endou Mamoru May 15 '17 at 12:46
  • @EndouMamoru: That is a C++ question rather than a SWIG/Python question. The answer is no, although you lose a lot of flexibility. You can do something called "explicit template instantiation". This will allow you to simply declare your function interfaces in the header /swig.i file. You are still forced to %template in the SWIG interface file, though, and you are restricted to the set of types for which you created explicit instantiations in the .cpp file. – AndyG May 15 '17 at 12:54
  • @AndyG: Thank you for the reply and help. Is there some nice documentation or information available regarding .i files? I am confused in the way we are writing it. We are including the hadder file but also we are writing the whole class definition in it, so why is that? – Endou Mamoru May 15 '17 at 13:01
  • @EndouMamoru: It's just one way to do it. You can instead leverage the %include directive which will greatly simplify your life. [Check the official doc](http://www.swig.org/Doc3.0/SWIGPlus.html#SWIGPlus_nn30) After you %include the header, you can use the %template directive to explicitly instantiate + rename classes/functions for your target languages. – AndyG May 15 '17 at 17:45

0 Answers0