c - 使 visual studio FORTRAN-C 混合代码 gfortran-gcc 兼容的最小修改

标签 c fortran mixed-programming

我正在尝试修改 this code ( gist as back up ) 与 gfortran-gcc 兼容。

  • 我删除了 [VALUE] 标签
  • POINTER-fcray-pointer 标志用于 gfortran,而不是 [REFERENCE] 标记
  • 删除了 __stdcall ,因为尝试了 #define __stdcall __attribute__((stdcall)) 导致 warning: 'stdcall' attribute ignored [-Wattributes] 现在这就是我所拥有的:

C代码CMAIN.C:

#include <stdio.h>

extern int FACT_(int n);
extern void PYTHAGORAS_(float a, float b, float *c);

main()
{
    float c;
    printf("Factorial of 7 is: %d\n", FACT_(7));
    PYTHAGORAS_(30, 40, &c);
    printf("Hypotenuse if sides 30, 40 is: %f\n", c);
}

FORTRAN 代码FORSUBS.FOR:

  INTEGER*4 FUNCTION Fact (n)
  INTEGER*4 n 
  INTEGER*4 i, amt
  amt = 1
  DO i = 1, n
    amt = amt * i
  END DO
  Fact = amt
  END

  SUBROUTINE Pythagoras (a, b, cp)
  REAL*4 a
  REAL*4 b
  POINTER (cp, c)
  REAL*4 c
  c = SQRT (a * a + b * b)
  END

Makefile:

all:
    gfortran -c FORSUBS.FOR -fcray-pointer
    gcc -c CMAIN.C
    gfortran -o result.out FORSUBS.o CMAIN.o  
    rm -rf *.o

clean :
    rm -rf *.out *~ *.bak *.o

但是我仍然得到错误:

CMAIN.o: In function `main':

CMAIN.C:(.text+0x1d): undefined reference to `FACT_(int)'

CMAIN.C:(.text+0x4c): undefined reference to `PYTHAGORAS_(float, float, float*)'

如果你能帮助我知道,我将不胜感激:

  • 问题是什么,我该如何解决?
  • 什么是修改原始代码以使其与 gcc-gfortran 兼容且变化最小的最佳方法。

P.S.1. 也在 Reddit 上分享过. P.S.2.操作系统和编译器规范与this question相同.

最佳答案

Fortran 通过引用传递变量,如任何 Fortran 到 C 教程的第一句话中所述。所以你:

  1. 不能只删除 [VALUE],您应该添加现代 VALUE 属性或更改 C 代码以传递指针。

  2. 不应在 [REFERENCE] 的 Fortran 端使用指针,而应将其删除。

  3. 为你的编译器使用实际的名字修饰,现在通常是 subroutine_name_(附加下划线,名字是小写的)或者使用现代的 bind(C, name="binding_name") 属性。

没有现代 Fortran,但有 VALUE(它只是一个没有的 PITA):

  INTEGER*4 FUNCTION Fact (n)
  INTEGER*4, VALUE :: n 
  INTEGER*4 i, amt
  amt = 1
  DO i = 1, n
    amt = amt * i
  END DO
  Fact = amt
  END

  SUBROUTINE Pythagoras (a, b, c) bind(C)
  REAL*4, VALUE :: a
  REAL*4, VALUE :: b
  REAL*4 c
  c = SQRT (a * a + b * b)
  END

并且不仅仅是将您的 C 名称更改为小写 (pythagoras_, fact_)... 使用 VALUE 属性您不需要介绍您在其他答案中看到的所有 C 临时变量。 bind(C)VALUE 正常工作所必需的。它将使您免于重写调用 Fortran 过程的代码。

为了获得最佳的现代体验,请使用 bind(C,name="any_name_you_want") 设置准确的链接符号名称。

关于c - 使 visual studio FORTRAN-C 混合代码 gfortran-gcc 兼容的最小修改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53585628/

相关文章:

在 C 中从 Fortran 调用全局字符串变量会导致段错误

c++ - MIXED_STR_LEN_ARG 与 gfortran

c++ - 加速 Matlab 引擎调用

c - 在ncurses中设置光标移动字段

连续分配与顺序分配

random_number() 在 GNU 和 PGI fortran 编译器之间给出了截然不同的行为

ubuntu - gfortran 编译目标文件错误 crt1.o : In function `_start' :

data-structures - Fortran90 中如何处理用户自定义的数据结构?

c - 以下程序中位掩码的使用来自 Programming Pearls

c - 为什么 C 编译器在为有符号类型分配过高的整数值时不发出警告?