【问题标题】:SWIG Python undefined symbol errorSWIG Python 未定义符号错误
【发布时间】: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 中。

标签: python c++ swig


【解决方案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,整个命令行可能如下:

    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

    【讨论】:

      【解决方案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
          猜你喜欢
          • 2021-05-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-02-03
          • 2013-08-17
          • 1970-01-01
          相关资源
          最近更新 更多