SWIG Python未定义符号错误

时间:2014-05-26 20:25:29

标签: python c++ swig

我试图创建一个* .so文件,以便在使用SWIG的Python中进一步使用,但有些东西不起作用。

我有两个文件: 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);
    }

};

和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();
};

我的spiController.i接口文件如下所示:

/* 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();

最后,我尝试使用终端中的命令创建* .so文件,如SWIG页面上的示例所示:

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和* .so文件创建没有错误,但是当我将spiController导入python代码时,我得到:

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

这是我第一次尝试使用SWIG,而且我已经陷入困境。我该如何解决这个问题?

6 个答案:

答案 0 :(得分:3)

您必须链接定义您已声明为checkStop等的C ++函数的库。您可以在示例的编译步骤的第3行添加-L<path to your C++ DLL> -l<name of your C++ DLL>

像这样:

c++ -L<path to DLL> -l<name of your dll> -shared spiController_wrap.o -o _spiController.so

答案 1 :(得分:2)

就像Adam的评论和我的经验一样,你应该首先将你的XXX.cpp文件编译成XXX.o,整个命令行可能如下:

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

2。 c ++ -c -fpic XXX.cpp (此命令将生成XXX.o文件)

3。 c ++ -c -fpic XXX_wrap.cxx -I / usr / include / python2.7 (此命令将生成XXX_wrap.o文件)

4。 c ++ -shared XXX.o XXX_wrap.o -o XXX.so

答案 2 :(得分:2)

我得到了同样的错误,最后弄清楚了原因。如上所述人们说,当它表示像你这样的未符号的符号并给出未定义的函数名'_Z9checkStopv'时,总是在.cpp文件中检查该函数的实现以及同名的任何函数声明!!

对于我的情况,我的cpp确实定义了我的'unfound symbol'构造函数,但在我的.h文件中,我有一个重载的operator =(对于构造函数),在.cpp文件中是未定义的。所以swig包装默认构造函数(在.cpp中实现)和operator =(未实现)。因此,导入时,此未实现的运算符=产生错误。希望这有帮助!

答案 3 :(得分:1)

虽然导致此问题的原因可能有很多,但是当我使用python v3.5标头编译共享库时,我得到了完全相同的错误,例如。

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

但后来尝试使用python test.py使用示例库,它在系统上运行python v2.7(所以这是一个python版本不匹配问题)。

答案 4 :(得分:0)

就我而言,我也遇到了该错误,并花了一些时间尝试一些东西而没有成功。我的问题是,尽管我的源文件是纯C语言,但假设它没关系,我却以.cpp扩展名命名。将扩展名更改为.c可以自动解决该问题。

解决此问题的另一种方法是将行#include "example.cpp"添加到SWIG .i文件的标题部分。

所以,总结一下:

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);

然后以下内容对我有用(在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)"

希望这对某人有帮助!
干杯

答案 5 :(得分:0)

我知道解决方法 在完成共享的最后,您应该usr g ++ -shared -fpic *。o * .o -o _ ***。so