从Fortran调用C ++(链接问题?) [英] Calling C++ from Fortran (linking issue?)
问题描述
我真的需要你的帮助!我在最后期限,我正在努力学习刚刚足以完成一些工作。现在已经过了一个多星期了,我处理的问题似乎是一个直截了当的问题,但是我无法在网上成功实施解决方案。
长篇故事short:我需要从F77调用C ++代码。我编译g ++和gfortran。我是一个完整的新手makefile。当这些代码被编译为它们各自的程序的一部分时,它们是无错误的(我从我的C ++代码,而不是main()函数,并试图使用它与fortran代码)。这是我的:
#include< cmath>
#include< vector>
using namespace std;
externCdouble ShtObFun(double x [],int& tp)
{
return // double precision awesomeness
}
Fortran代码:
子程序objfun(nv,var,f,impass)
隐含real(8)(ah,oz),integer(in)
c初始化包括tp,
$ bf = ShtObFun(var,tp)
return
end
b $ b
Makefile(仅显示上面列出的文件):
all:
g ++ -c Objective_Functions.cpp
gfortran -c -O3 opcase1.f
gfortran opcase1.o Objective_Functions.o -fbounds-check -lstdc ++ -g -o Program.out
rm * .o
错误:
opcase1.o:在函数'objfun_'中:
opcase1.f :( .text + 0xbd):未定义引用'shtobfun_'
collect2 :ld返回1退出状态
我尝试过各种其他方法,他们没有工作。如果需要,我可以稍后列出。
我已检查的网站:
从fortran调用C ++函数C ,
使用gcc链接fortran和c ++二进制文件,,从FORTRAN调用C代码, Cookbook - 从Fortran调用C , YoLinux - 一起使用C / C ++和Fortran
编辑(对第一个答案的回复):
如果我重写C ++代码为:
#include< cmath>
#include< vector>
using namespace std;
double ShtObFun(double x [],int& tp)
externCdouble shtobfun_(double * x,int * tp){
return ShtObFun * tp);
}
{
cout<< reached tp =<< tp<< endl;
exit(1);
}
我得到这个错误:
error: '
错误:在'{'token
之前的预期未限定标识符如果我将C ++代码重写为:
#include< cmath>
#include< vector>
using namespace std;
double ShtObFun(double x [],int& tp);
externCdouble shtobfun_(double * x,int * tp){
return ShtObFun(x,* tp);
}
double ShtObFun(double x [],int& tp)
{
cout< reached tp =<< tp<< endl;
exit(1);
}
代码将编译,但我得到的结果是reached tp = ,而应该说已达到tp = 1,因为我在fortran代码(整数tp = 1)中将tp初始化为1。如果我简单地声明该函数,我得到相同的问题:
externCdouble shtobfun_(double * x,int * tp)
{
// cout等etc
}
声明或别名
externCdouble ShtObFun(double x [ int& tp)
为
externCdouble shtobfun_(double x [],int& tp)
请参阅 http://gcc.gnu.org/onlinedocs/gcc /Weak-Pragmas.html
这是你的第一步。第二步是认识到Fortran不知道引用,而且它传递所有参数作为指针。所以你的F77接口应该声明为:
externCdouble shtobfun_(double x [],int * tp); double ShtObFun(double x [],int& tp)
externCdouble shtobfun_(double * x,int * tp){
return ShtObFun * tp);
}
I really need your help! I'm on a deadline and I'm trying to learn just enough to get some work done. It's been well over a week now that I'm dealing with what appears to be a straightforward issue but I haven't been able to successfully implement solutions online.
Long story short: I need to call C++ code from F77. I'm compiling with g++ and gfortran. I'm a complete newb to makefiles. When these codes are compiled as part of their respective programs, they are bug free (I'm taking a function from my C++ code, not main(), and trying to use it with the fortran code). Here's what I've got:
C++ Code:
#include <cmath>
#include <vector>
using namespace std;
extern"C" double ShtObFun(double x[], int &tp)
{
return //double precision awesomeness
}
Fortran Code:
subroutine objfun(nv, var, f, impass)
implicit real(8) (a-h,o-z), integer (i-n)
c initializations including tp, used below
f = ShtObFun(var, tp)
return
end
Makefile (shows only files listed above):
all:
g++ -c Objective_Functions.cpp
gfortran -c -O3 opcase1.f
gfortran opcase1.o Objective_Functions.o -fbounds-check -lstdc++ -g -o Program.out
rm *.o
Error:
opcase1.o: In function 'objfun_':
opcase1.f:(.text+0xbd): undefined reference to 'shtobfun_'
collect2: ld returned 1 exit status
I have tried this a variety of other ways and they did not work. I can list those later if requested. Does anyone see the issue here?
The sites I've checked:
calling C++ function from fortran not C,
Linking fortran and c++ binaries using gcc, , Calling C Code from FORTRAN, Cookbook - Calling C from Fortran, YoLinux - Using C/C++ and Fortran together
Edit (response to first answer):
If I rewrite C++ code as:
#include <cmath>
#include <vector>
using namespace std;
double ShtObFun(double x[], int &tp)
extern"C" double shtobfun_(double *x, int *tp) {
return ShtObFun(x, *tp);
}
{
cout << "reached tp = " << tp << endl;
exit(1);
}
I get this error:
error: expected initializer before 'extern'
error: expected unqualified-id before '{' token
If I rewrite C++ code as:
#include <cmath>
#include <vector>
using namespace std;
double ShtObFun(double x[], int &tp);
extern"C" double shtobfun_(double *x, int *tp) {
return ShtObFun(x, *tp);
}
double ShtObFun(double x[], int &tp)
{
cout << "reached tp = " << tp << endl;
exit(1);
}
The code will compile but the result I get is "reached tp = 0", while it should say "reached tp = 1" because I initialized tp to 1 in the fortran code (integer tp = 1). And I get the same issue if I simply declare the function as:
extern"C" double shtobfun_(double *x, int *tp)
{
//cout, etc
}
解决方案 declare or alias
extern"C" double ShtObFun(double x[], int &tp)
as
extern"C" double shtobfun_(double x[], int &tp)
see http://gcc.gnu.org/onlinedocs/gcc/Weak-Pragmas.html
That's you first step. Second step is to recognize that Fortran has no idea about references, moreover it passes all arguments as a pointer. so you F77 interface should be declared as:
extern"C" double shtobfun_(double x[], int *tp);
Putting it all together:
double ShtObFun(double x[], int &tp)
extern"C" double shtobfun_(double *x, int *tp) {
return ShtObFun(x, *tp);
}
这篇关于从Fortran调用C ++(链接问题?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!