我希望从我的 C++ 代码中调用 fortran 例程 cbesj.f,如何实现此目的?
以下是我已完成的步骤:
从 netlib amos 网页下载 cbesj.f 以及依赖项,http://www.netlib.org/cgi-bin/netlibfiles.pl?filename=/amos/cbesj.f
-
在源目录中,
f2c -C++PR *.f
g++ -c *.c
ar cr libmydemo.a *.o
-
[test_cbesj.cpp][1] 和
[mydemo.h][2]用于这样调用子程序,
g++ test_cbesj.cpp -lf2c -lm -L。 -lmydemo
它返回错误:
test_cbesj.cpp:(.text+0xd6): 对 `cbesj_(complex*, float*, long*, long*, complex*, long*, long*)' 的未定义引用
在我的问题中引用 cbesj_ 子例程的正确方法是什么?谢谢!
感谢凯西:
我认为你的方法是最好的。但我还是有错,为什么呢?开始了:
f77 -c *.f
在modemo.h中
//File mydemo.h
#ifndef MYDEMO_H
#define MYDEMO_H
#include <stdio.h> /* Standard Library of Input and Output */
#include "f2c.h"
extern"C" int cacai_(complex *z__, real *fnu, integer *kode, integer *mr, integer *n, complex *y, integer *nz, real *rl, real *tol, real *el\
im, real *alim);
extern"C" int cairy_(complex *z__, integer *id, integer *kode, complex *ai, integer *nz, integer *ierr);
extern"C" int casyi_(complex *z__, real *fnu, integer *kode, integer *n, complex *y, integer *nz, real *rl, real *tol, real *elim, real \
*alim);
extern"C" int cbesj_(complex *z__, real *fnu, integer *kode, integer *n, complex *cy, integer *nz, integer *ierr);
extern"C" int cbinu_(complex *z__, real *fnu, integer *kode, integer *n, complex *cy, integer *nz, real *rl, real *fnul, real *tol, real *el\
im, real *alim);
extern"C" int cbknu_(complex *z__, real *fnu, integer *kode, integer *n, complex *y, integer *nz, real *tol, real *elim, real *alim);
extern"C" int cbuni_(complex *z__, real *fnu, integer *kode, integer *n, complex *y, integer *nz, integer *nui, integer *nlast, real *fnul, \
real *tol, real *elim, real *alim);
extern"C" int ckscl_(complex *zr, real *fnu, integer *n, complex *y, integer *nz, complex *rz, real *ascle, real *tol, real *elim);
extern"C" int cmlri_(complex *z__, real *fnu, integer *kode, integer *n, complex *y, integer *nz, real *tol);
extern"C" int crati_(complex *z__, real *fnu, integer *n, complex *cy, real *tol);
extern"C" int cs1s2_(complex *zr, complex *s1, complex *s2, integer *nz, real *ascle, real *alim, integer *iuf);
extern"C" int cseri_(complex *z__, real *fnu, integer *kode, integer *n, complex *y, integer *nz, real *tol, real *elim, real *alim);
extern"C" int cshch_(complex *z__, complex *csh, complex *cch);
extern"C" int cuchk_(complex *y, integer *nz, real *ascle, real *tol);
extern"C" int cunhj_(complex *z__, real *fnu, integer *ipmtr, real *tol, complex *phi, complex *arg, complex *zeta1, complex *zeta2, complex\
*asum, complex *bsum);
extern"C" int cuni1_(complex *z__, real *fnu, integer *kode, integer *n, complex *y, integer *nz, integer *nlast, real *fnul, real *tol \
, real *elim, real *alim);
extern"C" int cuni2_(complex *z__, real *fnu, integer *kode, integer *n, complex *y, integer *nz, integer *nlast, real *fnul, real *tol \
, real *elim, real *alim);
extern"C" int cunik_(complex *zr, real *fnu, integer *ikflg, integer *ipmtr, real *tol, integer *init, complex *phi, complex *zeta1, complex\
*zeta2, complex *sum, complex *cwrk);
extern"C" int cuoik_(complex *z__, real *fnu, integer *kode, integer *ikflg, integer *n, complex *y, integer *nuf, real *tol, real *elim, re\
al *alim);
extern"C" int cwrsk_(complex *zr, real *fnu, integer *kode, integer *n, complex *y, integer *nz, complex *cw, real *tol, real *elim, real *a\
lim);
extern"C" real gamln_(real *z__, integer *ierr);
extern"C" integer i1mach_(integer *i__);
extern"C" real r1mach_(integer *i__);
extern"C" int xerror_(char *mess, integer *nmess, integer *l1, integer *l2, ftnlen mess_len);
#endif
在 test_case.c++ 中,
#include "mydemo.h"
#include "f2c.h"
#include <math.h>
#include <iostream>
#include <stdio.h>
#include <assert.h>
using namespace std;
int main(void)
{
// double x=86840.;
//int nu=46431,j, err;
complex *z,z__;
z__.r = 3.0;z__.i = 2.0;z = &z__;
cout << z->r << '\t' << z->i << endl;
real *fnu;float fnu__ = 3.0;fnu = &fnu__;
integer *kode ;long int kode__=1;kode=&kode__;
integer *n ;long int n__=1;n=&n__;
complex *cy;
integer *nz;
integer *ierr;
cbesj_(z, fnu, kode, n, cy, nz, ierr);
cout << cy->r << '\t' << cy->i << endl;
return 0;
}
Then,
g++ -c -g test_cbesj.cpp
g++ -o test *.o -lg2c
./test
3 2
Segmentation fault (core dumped)
gdb test
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /media/Downloads/amos-4/test...done.
(gdb) run
Starting program: /media/Downloads/amos-4/test
3 2
Program received signal SIGSEGV, Segmentation fault.
0x0804b355 in cbesj_ ()
(gdb) frame 0
#0 0x0804b355 in cbesj_ ()
(gdb) frame 1
#1 0x0805a3ca in main () at test_cbesj.cpp:21
21 cbesj_(z, fnu, kode, n, cy, nz, ierr);
感谢 roygvib 的回复!实际上是很好的建议。这是更改后的 test_cbesj.cpp:
complex z, cy;
float fnu;
long int kode, n, nz, ierr;
z.r = 3.0; z.i = 2.0;
fnu = 3.0;
n = 1; kode = 1;
cout.precision(16);
cbesj_( &z, &fnu, &kode, &n, &cy, &nz, &ierr );
cout << cy.r << '\t' << cy.i << endl;
cout << "nz=" << nz << endl;
cout << "ierr=" << ierr << Lendl;
不再有段错误。但由于某些原因,代码没有按预期工作:
./test
-1.343533039093018 -1.343533992767334
nz=0
ierr=4
答案是错误的, ierr 也在源代码中这么说:
C NZ - NUMBER OF COMPONENTS SET TO ZERO DUE TO UNDERFLOW,
C NZ= 0 , NORMAL RETURN
C NZ.GT.0 , LAST NZ COMPONENTS OF CY SET TO ZERO
C DUE TO UNDERFLOW, CY(I)=CMPLX(0.0,0.0),
C I = N-NZ+1,...,N
C IERR - ERROR FLAG
C IERR=0, NORMAL RETURN - COMPUTATION COMPLETED
C IERR=1, INPUT ERROR - NO COMPUTATION
C IERR=2, OVERFLOW - NO COMPUTATION, AIMAG(Z)
C TOO LARGE ON KODE=1
C IERR=3, CABS(Z) OR FNU+N-1 LARGE - COMPUTATION DONE
C BUT LOSSES OF SIGNIFCANCE BY ARGUMENT
C REDUCTION PRODUCE LESS THAN HALF OF MACHINE
C ACCURACY
C IERR=4, CABS(Z) OR FNU+N-1 TOO LARGE - NO COMPUTA-
C TION BECAUSE OF COMPLETE LOSSES OF SIGNIFI-
C CANCE BY ARGUMENT REDUCTION
C IERR=5, ERROR - NO COMPUTATION,
C ALGORITHM TERMINATION CONDITION NOT MET