【发布时间】:2018-07-10 13:35:57
【问题描述】:
我正在尝试在我用 Fortran 编写的程序中使用用 C++ 编写的库中的函数。 C++ 库汇总在一个头文件中,因此如果您想在另一个 C++ 程序中使用它,您只需执行 #include functions.h 我想了解如何在 Fortran 中执行类似操作。
根据我的研究,我创建了这个最小的可行示例:
clib/functions.h:
#ifndef ADD_H
#define ADD_H
extern "C"
{
int __stdcall add(int x, int y);
}
#endif
clib/functions.cpp:
extern "C"
{
int __stdcall add(int x, int y)
{
return x + y;
}
}
cinclude.c
#include "clib/functions.h"
cinterface.f95:
module cinterface
use,intrinsic::ISO_C_BINDING
integer(C_INT)::a,b
interface
integer(C_INT) function add(a,b) bind(C,name="add")
use,intrinsic::ISO_C_BINDING
implicit none
!GCC$ ATTRIBUTES STDCALL :: add
!DEC$ ATTRIBUTES STDCALL :: add
integer(C_INT), value ::a,b
end function add
end interface
end module cinterface
main.f90
program main
use cinterface
implicit none
integer :: c
c = add(1,2)
write(*,*) c
end program
制作文件:
FC = gfortran
CC = g++
LD = gfortran
FFLAGS = -c -O2
CFLAGS = -c -O2
OBJ=main.o
DEP = \
cinterface.o cinclude.o
.SUFFIXES: .f90 .f95 .c .o
# default rule to make .o files from .f files
.f90.o : ; $(FC) $(FFLAGS) $*.f90 -o $*.o
.f95.o : ; $(FC) $(FFLAGS) $*.f95 -o $*.o
.c.o : ; $(CC) $(CFLAGS) $*.c -o $*.o
%.o: %.mod
#
main.ex: ${DEP} ${OBJ}
$(LD) ${DEP} ${OBJ} -o prog.exe
#
当我尝试使用 Cygwin 制作这个项目时,出现以下错误:
main.o:main.f90:(.text+0x13): undefined reference to `add'
main.o:main.f90:(.text+0x13): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `add'
collect2: error: ld returned 1 exit status
make: *** [makefile:19: main.ex] Error 1
如何使 add 函数在 Fortran 中工作?
【问题讨论】:
-
在链接时,您还需要在函数中包含 C++ 对象。您可能指的是那个对象而不是
cinclude.o? [可能需要更多,但如果您尝试将其添加到链接中,我们可能会为您提供更多帮助。] -
@francescalus 很抱歉,您的意思是将
clib\functions.h添加到makefile 中或从clib\functions.cpp那里添加functions.o?因为在原始问题中添加从源文件创建的所有对象字段是不可能的(或至少不实用) -
是的,编译后的 C++ 代码必须在链接时可用(无论是在可执行对象中还是在某些动态方式中)。 Fortran 接口块只是说“我保证存在一个看起来像这样的符号” - 你仍然需要提供它,这就是 C++ 对象。
-
@francescalus 有没有办法直接从 C++ 标头向 Fortran 提供有关这些“承诺符号”的信息?
-
如此编辑。我还需要编辑
functions.c让它飞起来。现在它可以正确编译、链接和运行了。
标签: c++ fortran fortran-iso-c-binding