makefile — вызов функции C ++ из функции C ++, вызываемой кодом FORTRAN

Я пытаюсь отправить некоторые данные из кода 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

Я не смог скомпилировать код. Я не уверен, но я думаю, что-то не так с make-файлом, так как каждый раз, когда я меняю порядок объектных файлов, я получаю разные ошибки, такие как:

  /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'

Буду признателен за любую помощь по этому вопросу.

1

Решение

Как и в комментариях, добавьте правильную библиотеку времени выполнения для C ++ при связывании с компилятором Fortran.

FORTRAN_FLAG = -lstdc++ -o

С GCC вы можете даже просто сделать

gfortran *.cpp *.f90 -lstdc++ -o test.exe

Вы также можете связать с компилятором C ++ и добавить библиотеки Fortran к команде link.

Заметки нет iso_c_binding в любом месте вашего кода, даже если вы используете тег и ссылаетесь на него в заголовке. Это современный способ взаимодействия C и Fortran. Если вы хотите узнать больше о современных подходах, прочитайте тег вики-страницу.

2

Другие решения


По вопросам рекламы [email protected]