从 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++ 模板代码模块中未定义构造函数

使用 SWIG 为 Python 包装 C++。 “向量”未声明

SWIG:如何将复数向量从 C++ 传递到 python

SWIG:将异常从 Python 抛出到 C++

在 SWIG 中将结构从 C++ 函数返回到 Python

ImportError:使用 SWIG 时 _...so 文件中的未定义符号