我正在尝试将FORTRAN(f90)代码中的一些数据发送到C ++函数。简化的工作代码如下所示: 的 main.f90时:
program test
!
integer:: ii, jj, kk
common/ijk/ ii, jj, kk
character*32 cc
ii = 2
jj = 3
kk = 4
cc = 'Example of a character string'
!
call doubleIJK(cc)
!
write(*,*) ii, jj, kk
!
end program test
和 func.cpp :
#ifdef __cplusplus
extern"C" {
#endif
#include <stdio.h>
extern struct
{
int ii, jj, kk;
} ijk_;
void *__gxx_personality_v0;
int doubleijk_(char *cc, int ll)
{
cc[ll--] = '\0'; // NULL terminate the string
printf("From doubleIJK: %s\n",cc);
ijk_.ii *=2;
ijk_.jj *=2;
ijk_.kk *=2;
return(1);
}
#ifdef __cplusplus
}
#endif
和我的 Makefile :
# Compilers
FORTRAN_COMPILER = ifort
CPP_COMPILER = g++
# Flags
CPP_FLAG = -c #-lstdc++
FORTRAN_FLAG = -o
# Rules:
test.exe: main.o func.o
$(FORTRAN_COMPILER) $(FORTRAN_FLAG) test.exe main.o func.o
# Objects
func.o: func.cpp
($(CPP_COMPILER) $(CPP_FLAG) func.cpp)
main.o: main.f90
($(FORTRAN_COMPILER) $(CPP_FLAG) main.f90)
========================================
接下来,我想调用另一个cpp函数对func.cpp中现有的数据进行一些操作。过度简化的版本看起来像: 的 addition.cpp :
#include <iostream>
#include "addition.h"
using namespace std;
int addition (int a, int b)
{
int r;
r = a + b;
cout << r << endl;
return r;
}
addition.h :
#ifndef ADDITION_H
#define ADDITION_H
int addition (int a, int b);
#endif /* ADDITION_H */
更新的 Makefile :
# Compilers
FORTRAN_COMPILER = ifort
CPP_COMPILER = g++
# Flags
CPP_FLAG = -c #-lstdc++
FORTRAN_FLAG = -o
# Rules:
test.exe: main.o func.o addition.o
$(FORTRAN_COMPILER) $(FORTRAN_FLAG) test.exe main.o func.o addition.o
# Objects
func.o: func.cpp
($(CPP_COMPILER) $(CPP_FLAG) func.cpp)
addition.o: addition.cpp
($(CPP_COMPILER) $(CPP_FLAG) addition.cpp)
main.o: main.f90
($(FORTRAN_COMPILER) $(CPP_FLAG) main.f90)
我还将 func.cpp 更新为:
#ifdef __cplusplus
extern"C" {
#endif
#include <stdio.h>
#include "addition.h"
extern struct
{
int ii, jj, kk;
} ijk_;
void *__gxx_personality_v0;
int doubleijk_(char *cc, int ll)
{
cc[ll--] = '\0'; // NULL terminate the string
printf("From doubleIJK: %s\n",cc);
ijk_.ii *=2;
ijk_.jj *=2;
ijk_.kk *=2;
int z;
z = addition (5,3);
return(1);
}
#ifdef __cplusplus
}
#endif
我还没能编译代码。我不确定,但我想makefile有问题,因为每次我更改目标文件的顺序时,我会得到不同的错误,例如:
/tmp/cc4AuTkF.o(.text+0x50): In function `doubleijk_':
: undefined reference to `ijk_'
/tmp/cc4AuTkF.o(.text+0x58): more undefined references to `ijk_' follow
collect2: ld returned 1 exit status
make: *** [func.o] Error 1
或
func.o(.text+0x67): In function `doubleijk_':
: undefined reference to `addition'
addition.o(.text+0x23): In function `__static_initialization_and_destruction_0(int, int)':
: undefined reference to `std::ios_base::Init::Init()'
addition.o(.text+0x28): In function `__static_initialization_and_destruction_0(int, int)':
: undefined reference to `std::ios_base::Init::~Init()'
addition.o(.text+0x6f): In function `addition(int, int)':
: undefined reference to `std::cout'
我很感激在这个问题上的任何帮助。
答案 0 :(得分:2)
正如评论所示,在与Fortran编译器链接时为C ++添加正确的运行时库
FORTRAN_FLAG = -lstdc++ -o
使用GCC你甚至可以做到
gfortran *.cpp *.f90 -lstdc++ -o test.exe
您还可以链接到C ++编译器并将Fortran库添加到链接命令。
请注意,代码中没有iso_c_binding
,即使您使用标记并在标题中引用它。它是接口C和Fortran的现代方式。如果您想了解更多关于现代方法的信息,请阅读标签维基页面。