从 C++ 到 python 的 SWIG:未定义的符号导入问题

SWIG from c++ to python: undefined symbol import problem

我在将 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.h 文件中的函数 DLM,所以我不明白为什么会出现这个问题。另外,我在网上看到许多类似的问题,但 none 的建议解决方案有效。 谁能帮助解决这个问题?

提前致谢

PS:代码在内部使用库 Eigen,因为它可以在不同的建议文件中看到。

动态链接器抱怨未定义符号 _ZN5Param16read_AerogeneralEv

您确信它是在目标文件 DLM.o 中定义的。

请检查它是否实际定义在那个目标文件中

 nm DLM.o | grep _ZN5Param16read_AerogeneralEv

如果您看到以 T 开头的条目,则它已在此文件中定义。如果您只看到以 U 开头的条目,或者根本没有条目,那么它没有在此文件中定义。

如果已定义,请尝试在链接器命令行上重新排序对象文件(设 DLM.o 为最后一个对象)。

更有可能的是该符号实际上并未在那里定义。您需要调查为什么会出现这种情况并加以解决。

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 例程时不会出现任何错误。