编译求解器出现 undefined reference
-
各位朋友好!
我现在在compressibleInterFoam里面尝试添加空化模型,空化模型的组建参考interPhaseChangeFoam的思路,,编写的class “phaseChangeTwoPhaseMixture”用于组装空化源项,,wmake编译没有报错
但编译求解器myFoam(自己起的名字)时,就报错:
/project/zywang2/OpenFOAM/OpenFOAM-4.1/platforms/linux64GccDPInt32Opt/applications/solvers/multiphase/myFoam/myFoam.o: In function `main': myFoam.C:(.text.startup+0xcde): undefined reference to `Foam::phaseChangeTwoPhaseMixture::New(Foam::fvMesh const&)' myFoam.C:(.text.startup+0x2acd): undefined reference to `Foam::phaseChangeTwoPhaseMixture::New(Foam::fvMesh const&)' collect2: error: ld returned 1 exit status make: *** [/home/zywang2/OpenFOAM/zywang2-4.1/platforms/linux64GccDPInt32Opt/bin/myFoam] Error 1
自己看了好多前辈有关“undefined reference ”讨论的帖子,,目前自己分析有几种错误原因:
1、optional文件里面 关于phaseChangeTwoPhaseMixture的链接有问题
求解器的optional文件如下:EXE_INC = \ -ItwoPhaseMixtureThermo/lnInclude \ -IphaseChangeTwoPhaseMixtures/lnInclude \ -I(LIB_SRC)/thermophysicalModels/basic/lnInclude \ -I(LIB_SRC)/transportModels/interfaceProperties/lnInclude \ -I(LIB_SRC)/TurbulenceModels/compressible/lnInclude \ -I(LIB_SRC)/meshTools/lnInclude EXE_LIBS = \ -L$(FOAM_USER_LIBBIN) \ -ltwoPhaseMixtureThermo \ -lphaseChangeTwoPhaseMixtures \ -lcompressibleTransportModels \ -lfluidThermophysicalModels \ -lspecie \ -ltwoPhaseMixture \ -ltwoPhaseProperties \ -linterfaceProperties \ -lturbulenceModels \ -lcompressibleTurbulenceModels \ -lfiniteVolume \ -lfvOptions \ -lmeshTools
第二个原因是myFoam.C调用phaseChangeTwoPhaseMixture的格式不对,,具体就是creatFields.H中的应用代码:
#include "createPhi.H" Info<< "Constructing phaseChangeTwoPhaseMixture\n" << endl; autoPtr<phaseChangeTwoPhaseMixture> mixture = phaseChangeTwoPhaseMixture::New(mesh); volScalarField& alpha1(mixture->alpha1()); volScalarField& alpha2(mixture->alpha2());
同时,我自己查验了pahseChangeTwoPhaseMixture.H 和 .C文件,,感觉应该没有问题,编译通过,而且自己完全是参考interPhaseChangeFoam中对应的class写的
请哪位前辈指点能够一下呢?感激不尽
-
- 可能错误1 new函数没有定义,如果是定义了,那就是定义的形参和调用时的实参不是一个数据类型。
因为c++默认的函数重载,参数不同就是不同的函数。
- 可能错误2 新的class没有包含进编译时的链接库,就是你在尝试解决的方向。
用这个命令进入
cd $FOAM_USER_LIBBIN
看看新的class的so文件在不在。如果在,那基本就是可能错误1了。
- 另:编译class能过这点没有太大的说明意义。因为是个库文件,里面都是类的定义和成员函数,除了成员函数之间互相调用,不会有其他调用,所以很难出错。如果细看,也能看见myFoam.o是已经编译出来了的,错误是出在链接各.o文件。这时候就要检查调用了,就出错了。
-
@bestucan 感谢前辈的热心解答,根据前辈的建议,我目前认为我的问题应该是错误1。
我写的这个类phaseChangeTwoPhaseMixture,参考的是InterPhaseChangeFoam里的对应代码,不可压中该类应用RTS机制传递的参数是
Foam::phaseChangeTwoPhaseMixture::New ( const volVectorField& U, const surfaceScalarField& phi )
为了应用于可压缩,我将phaseChangeTwoPhaseMixture.C phaseChangeTwoPhaseMixture.H 和 newphaseChangeTwoPhaseMixture.C文件对应部分都改成了
Foam::phaseChangeTwoPhaseMixture::New ( const fvMesh& mesh )
在phaseChangeTwoPhaseMixture.H中定义代码如下:
public: //- Runtime type information TypeName("phaseChangeTwoPhaseMixture"); // Declare run-time constructor selection table declareRunTimeSelectionTable ( autoPtr, phaseChangeTwoPhaseMixture, components, ( const fvMesh& mesh //////////////////// ), (mesh) ); // Selectors //- Return a reference to the selected phaseChange model static autoPtr<phaseChangeTwoPhaseMixture> New ( const fvMesh& mesh /////////////////////// ); // Constructors //- Construct from components phaseChangeTwoPhaseMixture ( const word& type, const fvMesh& mesh ); //- Destructor virtual ~phaseChangeTwoPhaseMixture() {}
由于自己是个C++菜鸟,自己感觉就phseChangeTwoPhaseMixture这个class而言,内部的形参是mesh,,,外部我写的也是mesh,,我这个理解哪里出了问题呢?
麻烦前辈再指点一下,谢谢
-
@bestucan 感谢前辈的回复,,由于我这里要调用不同的空化模型,,所有要应用runTimeSelection机制,, newphaseChangeTwoPhaseMixture.C文件主要用于定义phaseChangeTwoPhaseMixture::New函数,,代码如下:
#include "phaseChangeTwoPhaseMixture.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Foam::autoPtr<Foam::phaseChangeTwoPhaseMixture> Foam::phaseChangeTwoPhaseMixture::New ( const fvMesh& mesh ) { IOdictionary transportPropertiesDict ( IOobject ( "transportProperties", mesh.time().constant(), mesh, IOobject::MUST_READ, IOobject::NO_WRITE, false ) ); word phaseChangeTwoPhaseMixtureTypeName ( transportPropertiesDict.lookup("phaseChangeTwoPhaseMixture") ); Info<< "Selecting phaseChange model " << phaseChangeTwoPhaseMixtureTypeName << endl; componentsConstructorTable::iterator cstrIter = componentsConstructorTablePtr_ ->find(phaseChangeTwoPhaseMixtureTypeName); if (cstrIter == componentsConstructorTablePtr_->end()) { FatalErrorInFunction << "Unknown phaseChangeTwoPhaseMixture type " << phaseChangeTwoPhaseMixtureTypeName << endl << endl << "Valid phaseChangeTwoPhaseMixtures are : " << endl << dictionaryConstructorTablePtr_->sortedToc() << exit(FatalError); } return autoPtr<phaseChangeTwoPhaseMixture>(cstrIter()(mesh));
我现在分析问题出现New函数,,我这里定义的New函数的形参是
const fvMesh& mesh
但phaseChangeTwoPhaseMixture里面形参是
// Constructors //- Construct from components phaseChangeTwoPhaseMixture ( const word& type, const fvMesh& mesh );
但感觉这里也没有影响吧,,debug好久仍然解决不了
有做过可压缩空化的朋友能够指点一下吗?
-
你这个,new是你自己起得函数名用来代替 phaseChangTwoPhaseMixture 这个函数的?
替代就直接替代,不能改名字啊。如果我没猜错,原始的调用代码是
phaseChangeTwoPhaseMixture(mesh);
这个不是函数调用,是类变量的隐性初始化(隐性初始化也用括号,容易和函数混),这是个声明类变量并赋值的过程,隐性初始化会调用构造函数并传递参数。那个和类名称同名的函数叫构造函数,必须和类名称一模一样。在声明该类变量时会自动调用构造函数。
也就是说,看着你在调用new函数,但是new函数是属于某个类对象的,而你没有声明这样的类对象,所以就找不到new函数。
改就直接改构造函数,不要换名字。要么复刻一个一模一样,只有类名不一样的类。
建议先看看C++,不用多么精,至少都浏览一遍有印象。你调试的这些时间用来浏览早就浏览完了…
-
@bestucan 感谢前辈的热心回复,目前问题已经解决,问题出现在类phaseChangeTwoPhaseMixture的make文件的files文件里面,
LIB = $(FOAM_USER_LIBBIN)/libphaseChangeTwoPhaseMixtures //会报错 LIB = (FOAM_USER_LIBBIN)/libtwoPhaseChange //随便叫一个名字均可,均可编译通过,但不能是libphaseChangeTwoPhaseMixtures
自己也是偶然发现的,但也比较困惑为什么这么神奇
不过最终问题还是解决了,很感谢前辈耐心的解答 ,自己后面也应该好好补一点C++知识