C 代码调用 Fortran 子程序时,子程序顶部出现分段错误

2024-01-01

我的文件中有 C++ 代码test-Q.cpp调用文件中的 Fortran 子例程getqpf.F。在文件中test-Q.cpp,我已将 Fortran 代码声明为外部代码,并且我正在使用getqpf_()名称修改约定。这gcc and gfortran编译器正在 GNU/Linux 上使用。

以下是 C++ 文件顶部的片段:

extern "C" {
            void  getqpf_  (double *tri, 
                    int nsamp, 
                    int lwin,
                    int nfreqfit, 
                    double dt, 
                    float null, 
                    int L2,
                    double df,
                    double *qq, 
                    double *pf, 
                    double *ampls, 
                    double *work1, 
                    double *work2, 
                    double *work3, 
                    double *work4,
                    int mem, 
                    int morder, 
                    int nfs, 
                    double *xReal, 
                    double *xImag, 
                    double *xAbs,
                    double *x1,
                    int cen,
                    int top,
                    int bot, 
                    float cut,
                    int nfst,
                    int raw);  

        } // end

以下是 Fortran 文件中的相应片段:

   subroutine getqpf (tri, nsamp, lwin, nfreqfit, dt, null, L2, df,
     1                   qq, pf, ampls, work1, work2, work3, work4,
     2                   mem, morder, nfs, xReal, xImag, xAbs, x1,
     3                   cen,top,bot, cut,nfst,raw)



      integer  morder, lwin, nsamp, nfreqfit, delay, nfs

      real     tri(*)
      real     qq(*), pf(*), ampls(*)

      real * 8 work1(*), work2(*), work3(*), work4(*)
      real * 8 xReal(*), xImag(*), xabs(*), x1(*)

      real * 8 dt8, cut8, df8
      real     null, cut
      integer  nfst
      logical  mem, L2, cen, top, bot, raw


      integer nf

C program logic code starts here
          nf = nfreqfit
          delay = 0
          dt8  = dt
          cut8 = cut

Fortran 代码调用其他 C 代码函数。在 GNU/Linux 上使用gfortran and gcc我已按以下方式编译并链接了所有文件:

 g++ -c test-Q.cpp -I./boost/boost_1_52_0/ -g
 gcc -c paul2.c -g
 gcc -c paul2_L1.c -g
 gcc -c paul6.c -g
 gcc -c paul6_L1.c -g 
 gcc -c fit_slope.c -g
 gfortran -c getqpf.F -g
 g++ -o test-Q test-Q.o paul2.o paul2_L1.o paul6.o paul6_L1.o fit_slope.o getqpf.o -g

尽管我能够成功构建二进制文件,但该行出现了段错误nf = nfreqfit。它位于 Fortran 文件的最顶部。跑步gdb二进制文件会产生以下输出:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000406fd3 in getqpf (tri=..., nsamp=Cannot access memory at address 0x3e9
) at getqpf.F:44
44        nf = nfreqfit

这里发生了什么,为什么会出现段错误?内存似乎没有在 C++ 代码和 Fortran 代码之间正确传递。

UPDATE

正如 IanH 在下面的答案中提到的,问题是由于没有通过引用传递参数造成的。使用 C++,该函数必须声明为:

 extern"C" {
            void  getqpf_  (float *tri, 
                    int &nsamp, 
                    int &lwin,
                    int &nfreqfit, 
                    float &dt, 
                    float &null, 
                    int &L2,
                    float &df,
                    float *qq, 
                    float *pf, 
                    float *ampls, 
                    double *work1, 
                    double *work2, 
                    double *work3, 
                    double *work4,
                    int &mem, 
                    int &morder, 
                    int &nfs, 
                    double *xReal, 
                    double *xImag, 
                    double *xAbs,
                    double *x1,
                    int &cen,
                    int &top,
                    int &bot, 
                    float &cut,
                    int &nfst,
                    int &raw);  

        } // end 

请注意 & 符号的存在。然后,可以在代码中调用该函数,如下所示:

getqpf_ (tri,       
    nsamp, 
    lwin,
    nfreqfit, 
    dt, 
    null, 
    L2,
    df,
    qq, 
    pf, 
    ampls, 
    work1, 
    work2, 
    work3, 
    work4,
    mem, 
    morder, 
    nfs, 
    xReal, 
    xImag, 
    xAbs,
    x1,
    cen,
    top,
    bot, 
    cut,
    nfst,
    raw); 

请注意,变量如nsamp被声明为int nsamp = 1001.


在赞同 M.S.B. 关于使用 F2003 的 C 互操作性的建议时,请注意,您的具体问题是按引用传递/按值传递不匹配(即使在使用 C 互操作性时,这仍然是您必须考虑的问题)。典型的 Fortran 实现通过引用传递所有参数,而在 C(++) 中默认是通过值传递。在 C++ 方面,请注意所有 int 和 float 参数以及一些 double 参数缺少指针说明符 (*)。这些参数是按值传递的 - 但 Fortran 方面没有任何内容表明这一点。在 F2003 之前,这通常是使用 Fortran 代码中的编译器特定指令来完成的。

使用 F2003 的 C 互操作,具有 BIND(C) 属性的过程参数的默认传递约定是通过引用。按值传递的参数需要在其声明中具有 VALUE 属性。

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

C 代码调用 Fortran 子程序时,子程序顶部出现分段错误 的相关文章

随机推荐

  • DynamoDB Stream 按顺序处理

    假设我有以下包含条目的 DynamoDB 表 A B C 列 a1 b1 c1 条目 1 a1 b2 c2 条目 2 A是键 分区键 B是排序键 唯一 C是属性 我想确保 DynamoDB 流可以保证 B 的按序处理 如果按此顺序进行更改
  • std::move_if_no except 仍然移动抛出仅移动类型的基本原理?

    move if noexcept http en cppreference com w cpp utility move if noexcept will 返回一个右值 促进移动 如果移动构造函数是noexcept 或者如果没有复制构造函数
  • Android Unity c#:写入保存游戏数据时发生 UnauthorizedAccessException

    我正在 Android 中调试 Unity 游戏 一切都在 Unity 编辑器中运行 在 Android 上保存当前游戏数据时 我收到 UnauthorizedAccessException 我正在写入持久数据路径 所以我不明白为什么访问被
  • Android 中在 jni 中运行的原生 C 代码与在 shell 中运行的区别

    我有一个原生 C Android 应用程序 首先 我将本机 C 代码构建到共享库中 jni 将使用该库 该库使用一些内核可加载模块 ko 一些已经加载 一些必须通过 insmod 命令加载 我还构建了一个使用该库的可执行文件 并且它可以通过
  • 延迟对服务器、JavaScript 的批量 GET 请求

    背景 我正在向服务器发出一批 HTTP GET 请求 我需要限制它们以避免杀死可怜的服务器 出于演示目的 这将是 GET 方法 This function simulates a real HTTP GET request that alw
  • 简单的C程序不打印输出[重复]

    这个问题在这里已经有答案了 我有一个简单的c程序 include
  • Hibernate 儿童计数标准

    我有父母 孩子关系 newsItem 1 评论 如何使用一个 Criteria 查询选择新闻项目列表以及每个新闻项目的评论计数 我想做这样的事情 select news item count comment id from news ite
  • 在 user.csv 上循环,然后在 jmeter 中循环 data.csv

    我需要做这样的事情 foreach user in a users csv foreach data in data csv send http request 我看过了这个帖子 https stackoverflow com questi
  • 将历史时间转换为 GMT

    我需要将格式为 2011061411322100 的一些字符串时间转换为 GMT 我的第一次尝试如下 但问题是 时间来自另一台电脑 而且是历史时间 所以我没有实时获取时间 所以我不能简单地从我的代码运行的盒子上的当地时间获取 GMT 问题是
  • 如何隐藏/取消隐藏代码镜像

    我想完全隐藏 取消隐藏代码镜像实例 是否有任何预定义的方法可以做到这一点 或者我是否需要以某种方式选择 div 并将其隐藏 根据文档 CodeMirror 的主编辑器对象有一个方法可以返回主包装 DOM 元素 cm getWrapperEl
  • php DateTime createFromFormat 功能

    您好 我似乎无法让日期时间方法按预期工作 我可能做错了什么 Passes OK dateTime DateTime createFromFormat d m Y 12 12 2012 var dump dateTime should fai
  • NUnit 中的执行顺序是什么?

    我一直在对测试驱动开发进行一些研究 发现它非常酷 我遇到的一件事是 当您编写测试时 设置和测试方法 Setup 和 Test 有一个执行顺序 测试时是否可以使用其他方法 如果可以 它们的执行顺序是什么 例如处置或其他什么 我看到了测试夹具的
  • 是否可以指示浏览器首先绘制页面的哪些元素?

    我想知道是否有任何方法可以控制浏览器绘制 例如我想首先加载页面顶部的元素 以便用户可以立即看到内容 页面底部的元素可以最后加载 因为用户在向下滚动之前不会看到它们 我正在寻求优化我的网站 该网站目前的加载时间为 6 秒 我希望将其降至 1
  • Redis 的内存使用量比数据多 10 倍

    我正在尝试在 redis 中存储单词列表 表演很棒 我的方法是制作一个名为 words 的集合 并通过 sadd 添加每个新单词 当添加一个 15 9 MB 且包含大约 100 万个单词的文件时 redis 服务器进程会消耗 160 MB
  • 在 React Native 中使用上下文

    在基于 Web 的 React 中 我们的 props 具有上下文 可以设置它并用作依赖注入机制 我想在 React Native 应用程序中做类似的事情 有什么办法可以做到这一点吗 React Native 使用相同的react用于 We
  • Google 基准测试 state.PauseTiming() 和 state.ResumeTiming() 需要很长时间

    我正在使用 google benchmark API 运行一些性能测试 我使用 state PauseTiming 和 state ResumeTiming 来避免不必要的代码段通过 perf 路径运行 我附上了下面的示例代码 while
  • 将 indesign 文件批量导出为 pdf,并为每个客户提供自定义页脚

    我有一个相当大的 Indesign 文件 其中有一个文本字段 需要为每个客户提供不同的文本 客户的姓名必须出现在文本字段中 例如 当我有 100 个客户时 我想自动导出 100 个 PDF 并且每个 PDF 在该字段中都有自己的自定义文本
  • 如何将 https://www.example.com 重定向到 https://example.com

    我环顾四周 似乎找不到明确的解决方案 我们的一些访问者或我们的访问者在我们的域中输入以下内容时遇到了一个小问题 https www example com 这是一个安全警告 该网站的安全证书存在问题 我们设置了 SSLexample com
  • 在不增加负载大小的情况下覆盖 vue 组件中的 bulma 变量 - Nuxt

    我的资产文件夹中有一个 main scss 文件 我用它来覆盖 bulma 变量 我通过 nuxt config 文件使该文件全局可用 import bulma sass utilities initial variables import
  • C 代码调用 Fortran 子程序时,子程序顶部出现分段错误

    我的文件中有 C 代码test Q cpp调用文件中的 Fortran 子例程getqpf F 在文件中test Q cpp 我已将 Fortran 代码声明为外部代码 并且我正在使用getqpf 名称修改约定 这gcc and gfort