Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SWIG Python undefined symbol error

Tags:

c++

python

swig

I'm trying to create a *.so file for further use in Python using SWIG, but something isn't working.

I have two files: DataGatherer.h

#include <iostream>
#include <stdlib.h>
#include <time.h>
#include "gnublin.h"
#include <pthread.h>

class dataGatherer
{
    private:
    int threshold;
    int timeThreshold;
    int data[4096];
    bool running;
    gnublin_spi* spiDevice;
    pthread_t spiThread;
    void *params;

    public:

    dataGatherer(void);
    dataGatherer(int, int);
    void initData();
    int getThreshold(void);
    int* getData(void);
    int getPeak(void);
    void initSPI(void);
    void gatherData();

    void * run(void * arg);
    void stop(void);

    // for use of thread we have to implement some methods from C
    static void * start_static(void * params)
    {
        dataGatherer * thread_this = static_cast<dataGatherer*>(params);
        return thread_this->run(thread_this->params);
    }

    void start(void * params)
    {
        this->params = params;
        pthread_create(&spiThread, 0, &dataGatherer::start_static, this);
    }

};

and spiController.h

#include "dataGatherer.h"

class spiController
{
    private:
    bool runGather;
    dataGatherer* gatherer;
    int data[4096];

    public:
    spiController(void);
    spiController(int, int);
    void initData();
    bool checkStop();
    void stop();
    void start();
};

My spiController.i interface file looks like this:

/* spiController.i */
%module spiController
%{
#include "dataGatherer.h"
#include "spiController.h"
#include "gnublin.h"
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
extern void initData();
extern bool checkStop();
extern void stop();
extern void start();
%}

extern void initData();
extern bool checkStop();
extern void stop();
extern void start();

At the end I try to create the *.so file using commands in the terminal like in the example on the SWIG page with:

swig -python -c++ spiController.i
c++ -c spiController_wrap.c -I/usr/include/python2.7
c++ -shared spiController_wrap.o -o _spiController.so

*.cxx, *.o and *.so file are created with no error, but when I import the spiController into the python code I get:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "spiController.py", line 26, in <module>
    _spiController = swig_import_helper()
  File "spiController.py", line 22, in swig_import_helper
    _mod = imp.load_module('_spiController', fp, pathname, description)
ImportError: ./_spiController.so: undefined symbol: _Z9checkStopv

It's my first try using SWIG and I'm already stuck at this point. How can I resolve this?

like image 739
quasit Avatar asked Dec 12 '22 05:12

quasit


2 Answers

I just got the same error and finally figured out why. As above people said, when it says unfound symbol like yours and gives the undefined function name '_Z9checkStopv', always check for the implementation of this function in .cpp file as well as any function declaration of the same name!!

For my case, my cpp does define my 'unfound symbol' constructor function, but in my .h file, i have an overloaded operator= (for the constructor) which is undefined in .cpp file. So swig wraps both default constructor(implemented in .cpp) and operator= (not implemented). Therefore when import, this unimplemented operator= produces the error. Hope this helps!

like image 120
ayy Avatar answered Dec 13 '22 17:12

ayy


You must link the library that defines your C++ functions that you have declared like checkStop etc. You would add -L<path to your C++ DLL> -l<name of your C++ DLL> on 3rd line of your example's compile steps.

Like this:

c++ -L<path to DLL> -l<name of your dll> -shared spiController_wrap.o -o _spiController.so
like image 24
Oliver Avatar answered Dec 13 '22 19:12

Oliver