如何从 C++ 调用 fortran 例程?

2023-12-08

我希望从我的 C++ 代码中调用 fortran 例程 cbesj.f,如何实现此目的?

以下是我已完成的步骤:

  1. 从 netlib amos 网页下载 cbesj.f 以及依赖项,http://www.netlib.org/cgi-bin/netlibfiles.pl?filename=/amos/cbesj.f

  2. 在源目录中,

    f2c -C++PR *.f

    g++ -c *.c

    ar cr libmydemo.a *.o

  3. [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

我下载了cbesj (or zbesj)和相关文件来自netlib,但由于某种原因,它们无法与 gfortran4.8(在 Linux x86_64 上)一起使用。更确切地说,cbesj总是给予ierr=4,虽然我无法编译zbesj因为zabs有太多参数(但请参阅下面的更新)。


所以我放弃使用原来的AMOS代码并尝试开放规范乐趣这也是基于AMOS的。我只需输入即可编译后者make(使用gfortran),生成了libopenspecfun.a等。然后我编写了以下代码来测试zbesj:

#include <cstdio>

extern "C" {
    void zbesj_( double *zr, double *zi, double *fnu, int *kode, int *n,
                 double *Jr, double *Ji, int *nz, int *ierr );
}

int main()
{
    int    n, nz, ierr, kode;
    double fnu, zr, zi, Jr, Ji;

    fnu = 2.5;
    zr = 1.0; zi = 2.0;
    n = 1; kode = 1;

    zbesj_( &zr, &zi, &fnu, &kode, &n, &Jr, &Ji, &nz, &ierr );

    printf( "fnu = %20.15f\n", fnu );
    printf( "z   = %20.15f %20.15f\n", zr, zi );
    printf( "J   = %20.15f %20.15f\n", Jr, Ji );
    printf( "nz, ierr = %d %d\n", nz, ierr );

    return 0;
}

并编译为

g++ test_zbesj.cpp libopenspecfun.a -lgfortran

这使

fnu =    2.500000000000000
z   =    1.000000000000000    2.000000000000000
J   =   -0.394517225893988    0.297628229902939
nz, ierr = 0 0

Because 这个网站说答案是-0.394517...+ 0.297628...i, 的结果zbesj似乎是正确的。


[Update]

通过更仔细地阅读原始代码并与openspecfun,发现用户需要取消注释适当的部分i1mach.f and r1mach.f (or d1mach.f)取决于机器环境。对于 Linux x86_64,取消注释标记为的部分似乎就足够了

C     MACHINE CONSTANTS FOR THE IBM PC

通过此修改,cbesj正确地与ierr=0;否则它给出ierr=4因为有些常量默认为0。对于双精度版本,我们还需要处理用户定义的ZABS,其定义与内在定义相冲突。英特尔 Fortran (ifort) 识别用户定义的ZABS这样并成功编译它们(尽管有很多警告),而 gfortran 因语法错误而停止编译(假设它是内在错误)。openspecfunc通过重写所有的来避免这个问题ZABS与内在的一。无论如何,通过上述修改cbesj and zbesj工作正常(如预期)。


[更新2]

事实证明,使用 BLAS 版本d1mach.f, r1mach.f, and i1mach.f,事情变得更加简单,因为它们自动确定与机器相关的常量,我们不需要手动修改代码。请参阅网络库/常见问题解答页面了解详细信息。同样的技巧也适用于 SLATEC(例如,这个page).

wget http://www.netlib.org/blas/i1mach.f 
wget http://www.netlib.org/blas/r1mach.f
wget http://www.netlib.org/blas/d1mach.f 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从 C++ 调用 fortran 例程? 的相关文章

  • 静态只读字符串数组

    我在我的 Web 应用程序中使用静态只读字符串数组 基本上数组有错误代码 我将所有类似的错误代码保存在一个数组中并检查该数组 而不是检查不同常量字符串中的每个错误代码 like public static readonly string m
  • 为什么在连接两个字符串时 Python 比 C 更快?

    目前我想比较 Python 和 C 用来处理字符串的速度 我认为 C 应该比 Python 提供更好的性能 然而 我得到了完全相反的结果 这是 C 程序 include
  • 使用 C# 登录《我的世界》

    我正在尝试为自己和一些朋友创建一个简单的自定义 Minecraft 启动器 我不需要启动 Minecraft 的代码 只需要登录的实际代码行 例如 据我所知 您过去可以使用 string netResponse httpGET https
  • C++ 是否可以在 MacOS 上与 OpenMP 和 boost 兼容?

    我现在已经尝试了很多事情并得出了一些结论 也许 我监督了一些事情 但似乎我无法完成我想要的事情 问题是 是否有可能使用 OpenMP 和 boost 在 MacOS High Sierra 上编译 C 一些发现 如果我错了请纠正我 Open
  • 如何填充 ToolStripComboBox?

    我发现它很难将数据绑定到ToolStripComboBox 好像没有这个ValueMember and DisplayMember特性 怎么绑定呢 访问toolstripcombobox中包装的组合框并访问其ValueMember Disp
  • 为什么在 WebApi 上下文中在 using 块中使用 HttpClient 是错误的?

    那么 问题是为什么在 using 块中使用 HttpClient 是错误的 但在 WebApi 上下文中呢 我一直在读这篇文章不要阻止异步代码 https blog stephencleary com 2012 07 dont block
  • 如何读取 Fortran 中内容不以空格分隔的 2D 文件

    我有一个矩阵存储在文件 number txt 中 如下所示 12323456 54254311 76534522 我如何在 Fortran 中读取这样的矩阵 结果将是 1 2 3 2 3 4 5 6 5 4 2 5 4 3 1 1 7 6
  • 使用 LINQ to SQL 时避免连接超时的最佳实践

    我需要知道在 net 应用程序中使用 LINQ to SQL 时避免连接超时的最佳实践 特别是在返回时IQueryable
  • 告诉 Nancy 将枚举序列化为字符串

    Nancy 默认情况下在生成 JSON 响应时将枚举序列化为整数 我需要将枚举序列化为字符串 有一种方法可以通过创建来自定义 Nancy 的 JSON 序列化JavaScript 原始转换器 https github com NancyFx
  • 为什么这个二维指针表示法有效,而另一个则无效[重复]

    这个问题在这里已经有答案了 这里我编写了一段代码来打印 3x3 矩阵的对角线值之和 这里我必须将矩阵传递给函数 矩阵被传递给指针数组 代码可以工作 但问题是我必须编写参数的方式如下 int mat 3 以下导致程序崩溃 int mat 3
  • C++ 中的双精度型数字

    尽管内部表示有 17 位 但 IEE754 64 位 浮点应该正确表示 15 位有效数字 有没有办法强制第 16 位和第 17 位为零 Ref http msdn microsoft com en us library system dou
  • 高效列出目录中的所有子目录

    请参阅迄今为止所采取的建议的编辑 我正在尝试使用 WinAPI 和 C 列出给定目录中的所有目录 文件夹 现在我的算法又慢又低效 使用 FindFirstFileEx 打开我正在搜索的文件夹 然后我查看目录中的每个文件 使用 FindNex
  • 使 Guid 属性成为线程安全的

    我的一个类有一个 Guid 类型的属性 该属性可以由多个线程同时读写 我的印象是对 Guid 的读取和写入不是原子的 因此我应该锁定它们 我选择这样做 public Guid TestKey get lock testKeyLock ret
  • Unity:通过拦截将两个接口注册为一个单例

    我有一个实现两个接口的类 我想对该类的方法应用拦截 我正在遵循中的建议Unity 将两个接口注册为一个单例 https stackoverflow com questions 1394650 unity register two inter
  • WebBrowser.Print() 等待完成。 。网

    我在 VB NET 中使用 WebBrowser 控件并调用 Print 方法 我正在使用 PDF 打印机进行打印 当调用 Print 时 它不会立即启动 它会等到完成整个子或块的运行代码 我需要确保我正在打印的文件也完整并继续处理该文件
  • 实体框架中的“it”是什么

    如果以前有人问过这个问题 请原谅我 但我的任何搜索中都没有出现 它 我有两个数据库表 Person 和 Employee 对每个类型的表进行建模 例如 Employee is a Person 在我的 edmx 设计器中 我定义了一个实体
  • 如何在richtextbox中使用多颜色[重复]

    这个问题在这里已经有答案了 我使用 C windows 窗体 并且有 richtextbox 我想将一些文本设置为红色 一些设置为绿色 一些设置为黑色 怎么办呢 附图片 System Windows Forms RichTextBox有一个
  • 使用 C 在 OS X 中获取其他进程的 argv

    我想获得其他进程的argv 例如ps 我使用的是在 Intel 或 PowerPC 上运行的 Mac OS X 10 4 11 首先 我阅读了 ps 和 man kvm 的代码 然后编写了一些 C 代码 include
  • 我可以在“字节数”设置为零的情况下调用 memcpy() 和 memmove() 吗?

    当我实际上没有什么可以移动 复制的时候 我是否需要处理这些情况memmove memcpy 作为边缘情况 int numberOfBytes if numberOfBytes 0 memmove dest source numberOfBy
  • 如何将十六进制字符串转换为无符号长整型?

    我有以下十六进制值 CString str str T FFF000 如何将其转换为unsigned long 您可以使用strtol作用于常规 C 字符串的函数 它使用指定的基数将字符串转换为 long long l strtol str

随机推荐

  • 如何在全息视图+散景中获得带有图例标签的全高垂直线?

    我想在其中绘制一条垂直线holoviews与bokeh后端有一个出现在我的图例中的标签 我需要这条线是绘图的完整高度 无论它是单独的还是与其他元素重叠 我怎样才能实现这个目标 Example 我在示例中添加了曲线图 因为否则即使可以出现在图
  • 如何无限制喷jsonFormat

    我正在实现一些使用 Spray 和 akka 的 REST API 该 API 应该公开某种用户 CRUD 我将在这个问题中仅使用创建用户 case class User id String name String case class R
  • 获取matplotlib颜色循环状态

    是否可以查询 matplotlib 颜色循环的当前状态 换句话说 有一个函数get cycle state会以下列方式表现 gt gt gt plot x1 y1 gt gt gt plot x2 y2 gt gt gt state get
  • SqlAlchemy 具有多个条件“and_”超过两个值的情况?

    根据下面的问题 具有多个条件的 SqlAlchemy 案例 我该如何使用下面and 没有得到错误too many values to unpack expected 2 type case Jobs interview type adsfa
  • R 中的 3D 绘图,更好的可见表面

    With my data我使用以下代码创建 library rugarch library fGarch fd lt as data frame modelfit which density color lt rgb 85 141 85 m
  • 在每个页面上放置一个 django 登录表单

    如果用户未登录 我希望登录表单 来自 django contrib auth 的 AuthenticationForm 出现在我网站的每个页面上 当用户登录时 他们将被重定向到同一页面 如果有错误 错误将与表单显示在同一页面上 我想您需要一
  • 如何构建 AOSP 应用程序?

    我正在尝试从 AOSP 构建相机应用程序 我使用的是 UBUNTU 14 04 我按照官方文档中的指南进行操作 最后我执行 make Camera 我收到以下错误 including system media audio utils And
  • 如何在 `polars::prelude::DataFrame` 上使用 `ndarray_stats::CorrelationExt`?

    我正在尝试计算 Rust 中数据框的协方差 这ndarray stats板条箱定义这样的函数对于数组 我可以从 a 生成一个数组DataFrame using to ndarray 如果我使用文档中的示例 编译器会很高兴 a 但是如果我尝试
  • 错误:R 中文件路径中出现意外的字符串常量

    我正在尝试在 R 中运行此命令以运行函数 xlsxToR lt function C Users Nabila Dropbox IsolutionsProject ServiceRequestTickets zip keep sheets
  • C 中的后台进程(守护进程)不是 execvp() -ing

    因此 我尝试运行后台进程并从中执行 execvp 当我输入 cp path file var tmp 时 该进程并未复制该文件 这是我的代码供参考 void cmd bg char command pid t process id 0 pi
  • 将子文档添加到现有 Solr 6.4 集合文档会创建重复文档

    这个问题类似于Solr 不会覆盖 重复的 uniqueKey 条目 但我所处的情况是 我有大量现有文档已添加到集合中 没有子文档 并且我正在使用 独立而不是云 Solr 6 4 而不是 5 3 1 我们最近启用了子文档 以便我们可以存储更丰
  • 为什么 getSpeed() 在 android 上总是返回 0

    我需要从 GPS 获取速度和航向 然而我唯一拥有的号码是location getSpeed 为 0 或有时不可用 我的代码 String provider initLocManager if provider null return fal
  • Java WebStart 和认可的目录

    如何在 java webstart jnlp 文件中指定我的某些 jar 正在覆盖 JRE 内置实现 就像常规应用程序上认可的 lib 属性一样 似乎没有办法在网络启动中定义认可的目录 即使将 java endorsed dirs 属性定义
  • IntelliJ 问题 -> 无法创建名为“Main”的类

    标题说明了我的问题 我收到此错误消息 无法创建类无法解析模板 Class 错误信息 选定的类文件名 Main java 映射到非 java 文件类型 通过 TextMate 捆绑包支持的文件 有人对我如何解决这个问题有任何想法吗 请检查文件
  • 拆分字符串列值

    acctcode primekey groupby lt columns WDS 1 NULL lt values varchar FDS 2 NULL IRN 3 NULL SUM 4 1 2 3 STL 5 NULL WTR 6 NUL
  • 扩展 Asp.NET MVC3 控制器类

    我是一位经验丰富的 NET 程序员 也是一位使用 PHP 的 MVC 程序员 现在我是 MVC3 的新手 并尝试在其上构建我的第一个作品 因此我正在处理一些问题 对于初学者来说 如何扩展控制器类 有人可以指出我应该实施的指南 方法列表吗 T
  • 无法释放 C 中的 const 指针

    我怎样才能释放一个const char 我使用分配新内存malloc 当我尝试释放它时 我总是收到错误 不兼容的指针类型 导致此问题的代码类似于 char name Arnold const char str const char mall
  • Android 获取当前时间戳?

    我想像这样获取当前时间戳 1320917972 int time int System currentTimeMillis Timestamp tsTemp new Timestamp time String ts tsTemp toStr
  • Jenkins:根据相同 Jenkins 作业中的每个构建步骤结果发送电子邮件

    我只是想知道如何发送电子邮件电子邮件分机插件基于相同 Jenkins 作业的每个构建步骤结果 这是我的场景 我的 Jenkins 工作有 3 个构建步骤 构建步骤1 Pull latest code from github and Buil
  • 如何从 C++ 调用 fortran 例程?

    我希望从我的 C 代码中调用 fortran 例程 cbesj f 如何实现此目的 以下是我已完成的步骤 从 netlib amos 网页下载 cbesj f 以及依赖项 http www netlib org cgi bin netlib