Я хочу вызвать подпрограмму fortran cbesj.f из своего кода на C++, и как мне этого добиться?
Вот шаги, которые я сделал:
Загрузите cbesj.f плюс зависимости с веб-страницы netlib amos, 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
в модемо.ч
//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_cbesj.cpp,
#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;
}
Затем,
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
f2c
? - person R Sahu   schedule 04.12.2015extern C
, чтобы имя функции, которое она ищет, не было искажено. - person Anon Mail   schedule 04.12.2015