链接 C++ 和 Fortran 时出现重复符号
Duplicate symbol when linking C++ and Fortran
我在 linking fortran 和 C++ 代码时遇到重复符号错误,我不知道为什么。
我有以下 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
并且我有以下 C++ 驱动程序,main.cpp
extern "C"
{
int __foo_MOD_bar;
void print();
}
int main()
{
__foo_MOD_bar = 42;
print();
return 0;
}
我想做的是将模块 foo/bar 变量分配给一个值并从 Fortran 子例程中打印它。
然而,当我编译并且link
gfortran -std=f2003 -fno-underscoring -c simple.f90
g++ -c main.c
gfortran main.o gfortran.o -o out
我收到重复符号错误
[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
我有点不知所措
您的 int __foo_MOD_bar;
定义了一个变量,而不仅仅是声明它(因为 extern "C"
块仅更改链接),并且 Fortran 代码大概也是这样做的。尝试向变量本身添加显式 extern
说明符,例如:
extern int __foo_MOD_bar;
(extern "C" int __foo_MOD_bar;
应该也可以在 extern "C"
块内部或外部使用 IIRC)。
或者,您可以在 Fortran 部分用声明替换变量定义,但我不懂那种语言,所以无法解释如何操作。
当对块使用extern "C"
时,块内的变量定义不会得到外部存储-class处理。这种行为有一个很好的理由,即像
这样的情况
extern "C" {
#include <some_c_lib.h>
}
使 C 头文件在 C++ 中可用。如果 extern "C" { ... }
将所有变量定义修改为外部声明,可能会发生不好的事情。
我在 linking fortran 和 C++ 代码时遇到重复符号错误,我不知道为什么。
我有以下 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
并且我有以下 C++ 驱动程序,main.cpp
extern "C"
{
int __foo_MOD_bar;
void print();
}
int main()
{
__foo_MOD_bar = 42;
print();
return 0;
}
我想做的是将模块 foo/bar 变量分配给一个值并从 Fortran 子例程中打印它。
然而,当我编译并且link
gfortran -std=f2003 -fno-underscoring -c simple.f90
g++ -c main.c
gfortran main.o gfortran.o -o out
我收到重复符号错误
[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
我有点不知所措
您的 int __foo_MOD_bar;
定义了一个变量,而不仅仅是声明它(因为 extern "C"
块仅更改链接),并且 Fortran 代码大概也是这样做的。尝试向变量本身添加显式 extern
说明符,例如:
extern int __foo_MOD_bar;
(extern "C" int __foo_MOD_bar;
应该也可以在 extern "C"
块内部或外部使用 IIRC)。
或者,您可以在 Fortran 部分用声明替换变量定义,但我不懂那种语言,所以无法解释如何操作。
当对块使用extern "C"
时,块内的变量定义不会得到外部存储-class处理。这种行为有一个很好的理由,即像
extern "C" {
#include <some_c_lib.h>
}
使 C 头文件在 C++ 中可用。如果 extern "C" { ... }
将所有变量定义修改为外部声明,可能会发生不好的事情。