我试图创建一个* .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,而且我已经陷入困境。我该如何解决这个问题?
答案 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
文件的标题部分。
所以,总结一下:
int fact(int n) {
if (n <= 1) return 1;
else return n*fact(n-1);
}
%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