Fortran 서브 루틴과 함께 C++ 코드를 컴파일 중입니다.C++/Fortran 혼합 프로그래밍 : 정의되지 않은 참조 '_gfortran_reshape_r8'
#include "Calculate.h"
extern "C" double SolveEq_(double *Gvalue, double *GvalueU, double *GvalueV, double *Gnodex, double *Gnodey, double *GtimeInc, double *Glfs);
template <class T1, class T2>
void Calculate(vector<Element<T1, T2> > &elm, GParameter &GeqPm, GmeshInfo &Gmesh)
{
// Solving Equation using Fortran code
SolveEq_(&Gmesh.Gvalue[0], &Gmesh.GvalueU[0], &Gmesh.GvalueV[0], &Gmesh.Gnodex[0], &Gmesh.Gnodey[0], &GeqPm.GtimeInc, &GeqPm.Glfs);
return;
}
그리고 포트란 코드 같은 것입니다 : :이 C++ CPP 코드는 같다
!==========================================================================
Module Inputpar
Implicit None
Integer,parameter :: Numx = 200, Numy = 200
End Module
!======================================== PROGRAM =============================================
Subroutine SolveEq(Gvalue, GvalueU, GvalueV, Gnodex, Gnodey, Deltat, Lfs);
Use Inputpar
Implicit None
Real*8 Deltat, Lfs, Dt, Su
Real*8 Gvalue(1, (Numx+1)*(Numy+1)), GvalueU(1, (Numx+1)*(Numy+1)), GvalueV(1, (Numx+1)*(Numy+1))
Real*8 Gnodex(0:Numx), Gnodey(0:Numy)
Real*8 DX, DY
Real*8 X(-3:Numx+3), Y(-3:Numy+3)
Real*8 VelX(-3:Numx+3,-3:Numy+3), VelY(-3:Numx+3,-3:Numy+3)
Real*8 G(-3:Numx+3,-3:Numy+3)
Common /CommonData/ X, Y, DX, DY, VelX, VelY, G, Dt, Su
!============================= Data Transfer ============================
Dt = Deltat
Su = Lfs
X (0:Numx) = Gnodex(0:Numx)
Y (0:Numy) = Gnodey(0:Numy)
VelX(0:Numx,0:Numy) = transpose(reshape(GvalueU,(/Numy+1,Numx+1/)))
VelY(0:Numx,0:Numy) = transpose(reshape(GvalueV,(/Numy+1,Numx+1/)))
G (0:Numx,0:Numy) = transpose(reshape(Gvalue ,(/Numy+1,Numx+1/)))
!==========Some other lines neglected here=================
End
!======================================== END PROGRAM =========================================
는 첫째 명령을 사용하여 포트란 코드를 컴파일 :
gfortran SolveEq.f90 -c -o SolveEq.o
를, 그리고, C++/포트란 컴파일 makefile을 사용하여 함께 코드 작성 :
# Compiler
CC = g++
# Debug option
DEBUG = false
# Source directory of codes
SRC1 = /home
SRC2 = $(SRC1)/Resources
SRC3 = $(SRC1)/Resources/Classes
OPT=-fopenmp -O2
ifdef $(DEBUG)
PROG=test.out
else
PROG=i.out
endif
# Linker
#LNK=-I$(MPI)/include -L$(MPI)/lib -lmpich -lopa -lmpl -lpthread
OBJS = libtseutil.a Calculate.o SolveEq.o
OBJS_F=$(OBJS)
SUF_OPTS1=$(OBJS_F)
SUF_OPTS2=-I$(SRC2)/
SUF_OPTS3=-I$(SRC3)/
SUF_OPTS4=
# Details of compiling
$(PROG): $(OBJS_F)
$(CC) $(OPT) -o [email protected] $(SUF_OPTS1)
%.o: $(SRC1)/%.cpp
$(CC) $(OPT) -c $< $(SUF_OPTS2)
%.o: $(SRC2)/%.cpp
$(CC) $(OPT) -c $< $(SUF_OPTS3)
%.o: $(SRC3)/%.cpp
$(CC) $(OPT) -c $< $(SUF_OPTS4)
# Clean
.PHONY: clean
clean:
@rm -rf *.o *.oo *.log
그러나 오류는 다음과 같이 표시됩니다.
g++ -fopenmp -O2 -o libtseutil.a Calculate.o SolveEq.o
Calculate.o: In function `void Calculate<CE_Tri, SolElm2d>(std::vector<Element<CE_Tri, SolElm2d>, std::allocator<Element<CE_Tri, SolElm2d> > >&, GParameter&, GmeshInfo&)':
Calculate.cpp:(.text._Z10CalculateGI6CE_Tri8SolElm2dEvRSt6vectorI7ElementIT_T0_ESaIS6_EER10GParameterR9GmeshInfo[_Z10CalculateGI6CE_Tri8SolElm2dEvRSt6vectorI7ElementIT_T0_ESaIS6_EER10GParameterR9GmeshInfo]+0x3c): undefined reference to `SolveEq_'
SolveEq.o: In function `solveeq_':
SolveEq.f90:(.text+0x2b8e): undefined reference to `_gfortran_reshape_r8'
SolveEq.f90:(.text+0x2d2a): undefined reference to `_gfortran_reshape_r8'
SolveEq.f90:(.text+0x2ec6): undefined reference to `_gfortran_reshape_r8'
SolveEq.f90:(.text+0x31fa): undefined reference to `_gfortran_reshape_r8'
collect2: error: ld returned 1 exit status
어떻게 된 일입니까?
간단한 컴파일을 사용하여 혼합 된 컴파일을 테스트했습니다.
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;
extern "C" double fortran_sum_(double *sum, double *su2m, double *vec, double* vec2, int *size);
int main(int argc, char ** argv)
{
int size;
double sum, sum2;
double aa,bb,cc,dd;
vector<double> vec;
vector<double> vec2;
size=2;
aa=1.0;
bb=2.0;
sum=0.0;
sum2=0.0;
vec.push_back(aa);
vec.push_back(bb);
vec2.push_back(aa*2.0);
vec2.push_back(bb*2.0);
fortran_sum_(&sum, &sum2, &vec[0], &vec2[0], &size);
cout << "Calling a Fortran function" << endl;
cout << "============================" << endl;
cout << "size = " << size << endl;
cout << "sum = " << sum << endl;
cout << "sum2 = " << sum2 << endl << endl;
}
그리고 포트란 코드이었다 : :이 C++ 코드이었다
gfortran fortran_sum.f90 -c -o fortran_sum.o
g++ fortran_sum.o call_fortran.cpp -o a.out
./a.out
그것은 잘 작동 :
Subroutine fortran_sum(gsum, gsum2, gvec, gvec2, gsize2)
integer gsize,gsize2
real*8 gvec(0:gsize2-1), gvec2(0:1)
real*8 gsum, gsum2
gsum = gvec(0)+gvec(1);
gsum2 = gvec2(0)+gvec2(1);
gsize = gsize*2;
end
그런 다음 컴파일 명령을 사용
Calling a Fortran function
============================
size = 2
sum = 3
sum2 = 6
간단한 프로그래밍을 테스트하기 위해 C++ 코드를 사용했습니다 : –
아마 libgfortran과 링크해야합니까? –
@ZetianRen, * nm * 또는 * objdump * 또는 컴파일러 모음의 해당 도구 (또는 운영 체제)가 있습니까? fortran_sum.o를보고 SolveEq_가 있는지 (또는 다른 변형 이름이 있는지) 확인할 수 있습니다. – blackpen