SWIG Python 未定义符号错误

Posted

技术标签:

【中文标题】SWIG Python 未定义符号错误【英文标题】:SWIG Python undefined symbol error 【发布时间】:2014-05-26 20:25:29 【问题描述】:

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

我有两个文件: 数据收集器.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,我已经陷入了困境。我该如何解决这个问题?

【问题讨论】:

_Z9checkStopv 是 checkstop 函数的错误名称。那个函数定义了吗? 你从来没有提到你的 .cpp 文件实际上有函数体。这些也必须链接到您的 .so 中。 【参考方案1】:

我刚刚得到了同样的错误,终于弄清楚了原因。正如上面人们所说,当它说像你这样的未找到符号并给出未定义的函数名称'_Z9checkStopv'时,请始终检查.cpp文件中该函数的实现以及任何同名的函数声明!

就我而言,我的 cpp 确实定义了我的“未找到符号”构造函数,但在我的 .h 文件中,我有一个重载的 operator=(用于构造函数),它在 .cpp 文件中未定义。所以 swig 包装了默认构造函数(在 .cpp 中实现)和 operator=(未实现)。因此,在导入时,这个未实现的 operator= 会产生错误。希望这会有所帮助!

【讨论】:

【参考方案2】:

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

像这样:

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

【讨论】:

不。这并不能解决问题。【参考方案3】:

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

    swig -python -c++ XXX.i

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

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

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

【讨论】:

【参考方案4】:

虽然这个问题可能有很多原因,但是当我使用 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版本不匹配的问题)。

【讨论】:

【参考方案5】:

在我的情况下,我也遇到了这个错误,并且花了一些时间尝试了一些东西但没有成功。我的问题是,虽然我的源文件是纯 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)"

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

【讨论】:

【参考方案6】:

我知道解决方案 补完分享后 usr g++ -shared -fpic *.o *.o -o _***.so

【讨论】:

1.swig -python -c++ example.i 2.g++ -c -fpic example.cpp 3.g++ -c -fpic example_wrap.cxx -I/usr/include/python3.5 4. g++ -shared -fpic example_wrap.o example.o -o _examplejava.so 下一步就是使用:python3

以上是关于SWIG Python 未定义符号错误的主要内容,如果未能解决你的问题,请参考以下文章

为 C 库生成 Python SWIG 绑定时未定义的符号

从 c++ 到 python 的 SWIG:未定义的符号导入问题 [关闭]

SWIG tcl:log4cpp 包装器的未定义符号错误

SWIG链接器:未定义的符号:_ZN2cv8fastFreeEPv(cv :: fastFree(void *))

Python 错误:在 SWIG 生成的 C++ 模板代码模块中未定义构造函数

痛饮错误:未定义的符号