使用 C++ 调用 Fortran 的 SDL:作用域和初始化程序错误

SDL with C++ calling Fortran: Scope and Initializer error

我想从旧的 Fortran 程序调用计算,但在 C++-SDL 例程中显示结果。

现在我已经阅读了所有与此相关的问题,但是在遵循所有规定之后我仍然遇到编译器错误。

相关代码片段如下:

SDL_wrapper.h:

extern "C++" void __stdcall callSomeFortran_();

SDL_wrapper.cpp:

#include "/usr/include/SDL/SDL.h"
#include "/usr/include/SDL/SDL_image.h"
#include <stdio.h>
#include "SDL_wrapper.h"
using namespace std;

int main(int argc, char *argv[])
{
   callSomeFortran(); 

    SDL_Surface *screen;
    (...)

fortranFunctions.f90:

subroutine callSomeFortran() bind(C)

    use iso_c_binding
    implicit none 

    write(*,*) 'Were in Fortran!'

end subroutine callSomeFortran

现在当我不在 main 中调用 callSomeFortran() 时,我可以用

完美编译

makefile

FLAGS = -lSDL -lstdc++

fortranFunctions: fortranFunctions.o wrapper.o
    gfortran -o fortranFunctions wrapper.o fortranFunctions.o $(FLAGS)

fortranFunctions.o: fortranFunctions.f90
    gfortran -c fortranFunctions.f90 -ffree-line-length-none -o fortranFunctions.o

但是因为我当然想调用该函数,所以我包含了它并得到了以下错误:

In file included from SDL_wrapper.cpp:5:0:
SDL_wrapper.h:1:29: error: expected initializer before ‘callSomeFortran_’
SDL_wrapper.cpp: In function ‘int main(int, char**)’:
SDL_wrapper.cpp:20:20: error: ‘callSomeFortran’ was not declared in this scope

我真的不明白。从我研究过的所有以前的帖子来看,这应该有效。此外,我已经有多年的编码经验,不知道范围应该有问题的地方。

我是不是遗漏了什么明显的东西?

extern "C++" void __stdcall callSomeFortran_();

错了。

  1. 您在 Fortran 中将其声明为

    callSomeFortran() bind(C)
    

bind(C) 意味着(不仅)不会附加尾随下划线,您也不应该在 C++ 中附加它。最好明确地写成 bind(C,name="callSomeFortran")

  1. 我没有看到 __stdcall 的任何理由,我认为您使用的是默认调用约定。

  2. 应该是extern "C"{},不是"C++"。您希望它具有 C 链接。

extern "C"bind(C) 做的事情非常相似。强制过程遵循简单的 C 调用约定。这意味着对于 Fortran 和 C++,过程的符号将是函数的名称,没有任何变化。对于 Fortran,它还意味着所有变量都将使用指向它们的指针传递,除非声明为 value.

如果没有 bind(C),符号的名称将附加 _,但此行为因编译器而异。另外,对于模块程序,它更复杂。

如果没有extern "C",符号的名称会很复杂,规则也不规范。