【发布时间】:2019-08-13 15:41:10
【问题描述】:
我想开发一个 Fortran 静态库,其中包含一个需要很长时间才能完成的自定义子例程。 这个静态库也将静态链接到我的 C++ 应用程序中。
我的目标是监控我的 C++ 应用程序中此子例程的当前状态实时。
因此,对于“fortran 循环”的每个步骤,我想将循环索引发送到我的 C++ 应用程序。
我是 Fortran 世界的新手,所以我想这个任务可能是这样的:
我的 C++ 标头:
extern "C" void fortran_status(int* value);
我的 Fortran-90 文件:
module my_interfaces
use iso_c_binding
interface
subroutine fortran_status(progress_value) bind(C, name = 'fortran_status')
use, intrinsic :: iso_c_binding
integer(c_int), intent(out) :: progress_value
end subroutine fortran_status
end interface
end module my_interfaces
! My long calc subroutine
subroutine my_long_calc(progress_value) BIND(C, name = 'my_long_calc')
use, intrinsic :: ISO_C_BINDING
use my_interfaces
implicit none
EXTERNAL fortran_status
integer (C_INT), INTENT(INOUT) :: progress_value
integer (C_INT) :: count
do count = 0, 5
progress_value = progress_value + 1
! Send 'progress_value' to a C++ function:
call fortran_status(progress_value)
! Wait 1 second:
call sleep(1)
end do
end subroutine my_long_calc
这个 Fortran 代码给了我一个编译时错误:
error #6406: Conflicting attributes or multiple declaration of name. [FORTRAN_STATUS] C:\Users\lamar\Desktop\Lib1_interface\Lib1.f90 18
我正在使用 Microsoft Visual Studio 2019 和 Intel Visual Fortran (Windows 10 x64)。
我如何监控该子程序的状态?或者在我的 C++ 应用程序中获取 fortran 循环索引?
更新 1:
我删除了EXTERNAL fortran_status,现在我的 Fortran 代码的编译时没有错误。
现在,我想将此静态库 (x86) 与我的 C++ 代码链接:
#include <iostream>
extern "C" {
void my_long_calc(void);
void fortran_status(int* value);
}
void fortran_status(int* value)
{
std::cout << "Fortran current status = " << *value << std::endl;
}
int main (void)
{
std::cout << "Monitoring Fortran subroutine..." << std::endl;
my_long_calc();
return 0;
}
我正在尝试使用 MingW 编译和链接它:
g++ -Wall -L. .\Lib2.lib -lgfortran .\main.cpp -o app.exe
我得到了这个链接器错误:
undefined reference to my_long_calc
如何链接?
我想在我的终端输出中看到:
Monitoring Fortran subroutine...
Fortran current status = 0
Fortran current status = 1
Fortran current status = 2
Fortran current status = 3
Fortran current status = 4
Fortran current status = 5
更新 2
现在这个更改的 Fortran 代码可以编译,并且只有在我使用 MingW g++ (x86) 时才能正常工作。
Fortran 代码:
module my_interfaces
use iso_c_binding
interface
subroutine fortran_status(progress_value) bind(C, name = 'fortran_status')
use, intrinsic :: iso_c_binding
integer(c_int), intent(out) :: progress_value
end subroutine fortran_status
end interface
end module my_interfaces
! My long calc subroutine
subroutine my_long_calc() BIND(C, name = 'my_long_calc')
use, intrinsic :: ISO_C_BINDING
use my_interfaces
implicit none
integer (C_INT) :: progress_value
integer (C_INT) :: count
progress_value = 0
do count = 0, 5
progress_value = count
! Send 'progress_value' to a C++ function:
call fortran_status(progress_value)
! Wait 1 second:
call sleep(1)
end do
end subroutine my_long_calc
C++ 代码:
#include <iostream>
extern "C" {
void my_long_calc(void);
void fortran_status(int* value);
}
void fortran_status(int* value)
{
std::cout << "Fortran current status = " << *value << std::endl;
}
int main (void)
{
std::cout << "Monitoring Fortran subroutine..." << std::endl;
my_long_calc();
return 0;
}
编译c++:g++ -Wall -c .\main.cpp
编译fortran:gfortran -c .\gfortran.f90
链接在一起:g++ .\main.o .\gfortran.o -o app.exe -lgfortran
现在的问题是我需要使用 Visual Studio 2019 和 Visual Fortran 来开发我的 Fortran 代码。 我想使用 Visual Studio 将所有 Fortran 代码编译成一个单个静态库 (*.lib) 文件。
我需要更改什么才能使用 MingW g++ 命令链接 *.lib 文件(来自 Visual Fortran)?
我正在考虑使用这样的东西:
g++ main.cpp my_lib.lib -o app.exe
但我收到此链接器错误:
undefined reference to my_long_calc
我需要做什么?
【问题讨论】:
-
您不应该使用
external fortran_status,因为您已经在模块中对该接口进行了定义。所以我们可以进一步解释一下,为什么你认为external声明是必要的? -
谢谢@francescalus!你说的对!现在我的 fortran 代码在编译时没有错误。谢谢!
-
完整答案和一些细节在这里:software.intel.com/en-us/forums/…
标签: fortran intel-fortran