Uzbieram zduplikowany błąd symbolu podczas łączenia kodu fortran i C ++, a ja jestem straty, dlaczego.

Mam następujący kod fortran, simple.f90:

module foo
    use iso_c_binding
    integer(kind=c_int) :: bar
end module foo

subroutine print()
    use foo
    write(*,*) bar
end subroutine print

I mam następujący kierowca C ++, Main.CPP


extern "C"
{
  int __foo_MOD_bar;
  void print();
}


int main()
{
  __foo_MOD_bar = 42;
  print();
  return 0;
}

Co chciałbym zrobić, jest przypisać zmienną foo / bar modułu do wartości i wydrukować go z wręcznika Fortran.

Jednak kiedy kompilację i link

gfortran -std=f2003 -fno-underscoring -c simple.f90
g++ -c main.c
gfortran main.o gfortran.o -o out

Dostaję zduplikowany błąd symbolu

[100%] Linking CXX executable out
duplicate symbol '___foo_MOD_bar' in:
    CMakeFiles/out.dir/main.cpp.o
    CMakeFiles/out.dir/simple.f90.o
ld: 1 duplicate symbol for architecture x86_64
 nm simple.f90.o
00000000000000f8 s EH_frame1
00000000000004cc S ___foo_MOD_bar
                 U __gfortran_st_write
                 U __gfortran_st_write_done
                 U __gfortran_transfer_integer_write
0000000000000000 T _print
0000000000000078 s lC0
nm main.cpp.o
0000000000000388 S ___foo_MOD_bar
0000000000000000 T _main
                 U _print

Jestem trochę straty

0
Chris 14 marzec 2020, 01:06

2 odpowiedzi

Najlepsza odpowiedź

Twoja int __foo_MOD_bar; definiuje zmienną i nie tylko go deklaruje (jak blokada bloków extern "C". Spróbuj dodać wyraźny opis {X2}} do samej zmiennej, jak:

extern int __foo_MOD_bar;

(extern "C" int __foo_MOD_bar; powinien pracować jako iirc, wewnątrz lub na zewnątrz bloku extern "C").

Alternatywnie, możesz zastąpić zmienną definicję z deklaracją w części fortran, ale nie wiem, że ten język, więc nie potrafię wyjaśnić, jak.

1
numzero 13 marzec 2020, 22:17

Podczas stosowania extern "C" za pomocą bloku, definicje zmiennych wewnątrz bloku nie otrzymują zewnętrznej klasie do przechowywania. Jest dość dobry powód tego zachowania, a mianowicie przypadki

extern "C" {
#include <some_c_lib.h>
}

Aby wprowadzić pliki nagłówka C użyteczne w C ++. Jeśli extern "C" { ... } miał modyfikować wszystkie zmienne defintacje w deklaracjach zewnętrznych, mogą się zdarzyć złe rzeczy.

1
Hristo 'away' Iliev 13 marzec 2020, 22:41