简体   繁体   中英

SWIG Python undefined symbol error

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?

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!

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

正如 Adam 的评论和我的经验,您应该首先将XXX.cpp文件编译为XXX.o ,整个命令行可能如下所示:

  1. swig -python -c++ XXX.i

  2. g++ -c -fpic XXX.cpp* (this command will generate XXX.o file)

  3. g++ -c -fpic XXX_wrap.cxx -I/usr/include/python2.7* (this command will generate XXX_wrap.o file)

  4. g++ -shared XXX.o XXX_wrap.o -o XXX.so

Although there may be many causes for this problem, I got the exact same error when I compiled the shared library with the python v3.5 headers, eg

swig -python example.i
gcc -fPIC -c example.c example_wrap.c -I/usr/include/python3.5 # <-- ISSUE HERE
gcc -shared example.o example_wrap.o -o _example.so

But then later tried to use the example library using python test.py , which ran python v2.7 on system (so it was a python version mismatch issue).

In my case I was also getting that error, and spent some time trying out stuff without success. My problem was that although my source file was plain CI had it named with the .cpp extension, assuming it wouldn't matter. Changing the extension to .c solved automatically the issue.

Another way of solving it was to add the line #include "example.cpp" to the header section of SWIG's .i file.

So, summarizing:

example.c

int fact(int n) {
  if (n <= 1) return 1;
  else return n*fact(n-1);
}

example.i

%module example
%{
  extern int fact(int n);
%}
extern int fact(int n);

Then the following worked for me (in Ubuntu 17.10):

swig -c++ -python example.i
gcc -fPIC -c example.c example_wrap.c -I /usr/include/python2.7
gcc -shared example.o example_wrap.o -o _example.so
python -c "import example; print example.fact(5)"

Hope this helps someone!
Cheers

我知道解决办法 在make up the share的最后,你应该 usr g++ -shared -fpic *.o * .o -o _***.so

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM