从 c++ 到 python 的 SWIG:未定义的符号导入问题 [关闭]
Posted
技术标签:
【中文标题】从 c++ 到 python 的 SWIG:未定义的符号导入问题 [关闭]【英文标题】:SWIG from c++ to python: undefined symbol import problem [closed] 【发布时间】:2018-09-11 17:02:57 【问题描述】:我在将 c++ 函数转换为 python 时遇到了一些问题。我的函数包含在我的头文件中:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <cmath>
#include <math.h>
#include <complex>
#include <tgmath.h>
#include <iostream>
#include <Eigen/Core>
// Classes used in the wrapped function DLM
#include "Param.h"
#include "Wingsegment.h"
#include "Modes.h"
#include "IPS.h"
#include "Dlattice.h"
#include "Strmesh.h"
#include "Aeromesh.h"
void DLM( std::string DLM_inputfile, std::vector<double>
&Qhh_std_real, std::vector<double> &Qhh_std_imag,
std::vector<double> &omegavector_std, int &nModes, int
&nOmega );
std::string return_format_modes() ;
为了澄清,我将插入DLM.cpp
代码的一部分:
#include "DLM.h"
std::string format_modes; // Global variable
void DLM( std::string DLM_inputfile, std::vector<double>
&Qhh_std_real, std::vector<double> &Qhh_std_imag,
std::vector<double> &omegavector_std, int &nModes, int
&nOmega )
const std::string config_file_name = DLM_inputfile;
Param PARAM;
PARAM.read_DLM_input( config_file_name);
PARAM.read_General();
PARAM.read_Aerogeneral(); //<-- here apparently the issue
...
;
鉴于这个 c++ 函数,这里是 SWIG pyDLM_Cpp.i
的文件:
%module pyDLM_Cpp
%
/* Every thing in this file is being copied in
wrapper file. We include the C header file necessary
to compile the interface */
#include "./dlm/DLM.h"
#include "./dlm/Param.h"
%
%include "std_vector.i";
%include "std_string.i";
namespace std
%template(DoubleVector) vector<double>;
;
%include "./dlm/DLM.h";
%include "./dlm/Param.h";
我使用的 Makefile(看起来像工作文件):
EIGEN_PATH = path/to/eigen
INCLPATH = -I$(EIGEN_PATH)
all:
swig -c++ -python -Wall pyDLM_Cpp.i
g++ -O2 -c -std=gnu++11 -fPIC ./dlm/DLM.cpp
$(INCLPATH)
g++ -O2 -c -std=gnu++11 -fPIC pyDLM_Cpp_wrap.cxx -
I/usr/include/python2.7 $(INCLPATH)
g++ -O2 -shared -fPIC DLM.o pyDLM_Cpp_wrap.o -o
_pyDLM_Cpp.so
现在,当我尝试将我的函数导入 python 时,我得到的错误是:
ImportError: ./_pyDLM_Cpp.so: undefined symbol:
_ZN5Param16read_AerogeneralEv
现在,函数 Param::read_Aerogeneral() 在 Param.h
中声明为在 DLM.cpp
文件的第一行中定义的对象 Param 的成员,并且不直接在 Python 中使用,它仅调用函数 DLM 在DLM.h 文件,所以我不明白为什么会出现这个特定问题。另外,我在网上看到了许多类似的问题,但提出的解决方案都没有奏效。
任何人都可以帮助解决这个问题吗?
提前致谢
PS:代码在内部使用库 Eigen,因为它可以在不同的建议文件中看到。
【问题讨论】:
请提取minimal reproducible example。另外,请务必对错误的含义进行一些研究。 【参考方案1】:动态链接器抱怨符号_ZN5Param16read_AerogeneralEv
未定义。
您确信它是在目标文件DLM.o
中定义的。
请检查它是否真的在那个目标文件中定义了
nm DLM.o | grep _ZN5Param16read_AerogeneralEv
如果您看到以T
开头的条目,那么它是在此文件中定义的。如果您只看到一个以U
开头的条目,或者根本没有条目,那么它没有在此文件中定义。
如果已定义,请尝试在链接器命令行上重新排序对象文件(让DLM.o
成为最后一个对象)。
更可能的是,该符号实际上并未在此处定义。您需要调查为什么会出现这种情况并加以解决。
【讨论】:
【参考方案2】:T。 Herzke 的回答实际上很有帮助。发现有问题的符号 _ZN5Param16read_AerogeneralEv
仅在 Param.o
中定义,如果在 makefile 中指定如下,则构建:
g++ -O2 -c -std=gnu++11 -fPIC ./dlm/DLM.cpp ./dlm/Param.cpp
$(INCLPATH) # need to add the Param.cpp
然后将Param.o
添加到_pyDLM_Cpp.so
大楼:
g++ -O2 -shared -fPIC DLM.o Param.o pyDLM_Cpp_wrap.o -o
_pyDLM_Cpp.so # need to add the Param.o
以这种方式构建接口在导入我的 python 例程时不会出现任何错误。
【讨论】:
以上是关于从 c++ 到 python 的 SWIG:未定义的符号导入问题 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
Python 错误:在 SWIG 生成的 C++ 模板代码模块中未定义构造函数