我试图将结构"stuff"从C传递到Fortran。"stuff"有一个成员"gef",它包含两个变量"name"和"extra"。在调用Fortran例程test2之前,stuff. gef和stuff_gef都是好的,但当我进入Fortran时,"name"和"extra"变量是坏的。
更新:原来的问题解决了,但是我被推荐在Fortran结构上使用BIND(C)。我尝试了但是得到了一个编译错误,因为指针不允许与BIND(C)限定符一起使用。我需要指针变量来将外部(_ext)Fortran结构Map到C结构,因为内部版本具有不能与C互操作的可分配数组
C代码:
#include <iostream>
#include <cstddef>
#include <vector>
using namespace std;
extern "C" {
struct t_stuff_gef {
char name[256];
double extra;
double* p_var;
};
struct t_stuff {
t_stuff_gef gef;
};
void test2(t_stuff *stuff);
}
int main()
{
t_stuff stuff;
strcpy_s(stuff.gef.name, sizeof(stuff.gef.name), "Teststuff");
stuff.gef.extra = 100.0;
stuff.gef.p_var = new double[2];
stuff.gef.p_var[0] = 123.0;
stuff.gef.p_var[1] = 456.0;
test2(&stuff);
}
Fortran代码:
module ftncode_mod
use, intrinsic :: iso_c_binding
implicit none
!--external structure, same as C
type, public :: t_stuff_gef_ext
character(1) :: name(256)
real(8) :: extra
real(8), pointer :: var
end type t_stuff_gef_ext
!--internal structure, to be be populated from the interface structure above
type, public :: t_stuff_gef
character(1) :: name(256)
real(8) :: extra
real(8), allocatable :: var(:)
end type t_stuff_gef
type, public :: t_stuff_ext
type(t_stuff_gef_ext) :: gef
end type t_stuff_ext
contains
subroutine test2(stuff_ext) bind(C)
!DEC$ATTRIBUTES DLLEXPORT :: test2
type(t_stuff_ext), target , intent(in) :: stuff_ext
type(t_stuff_gef) :: stuff_gef
integer :: i
real(8) :: k
pointer (p_k,k)
p_k = loc(stuff_ext%gef%var)
allocate(stuff_gef%var(2))
do i = 1, 2
stuff_gef%var(i) = k
p_k = p_k + sizeof(k)
enddo
print *, stuff_gef%var(1)
print *, stuff_gef%var(2)
return
end
end module
这段代码可以工作,但不需要BIND(C)限定符。
2条答案
按热度按时间yvfmudvl1#
下面的代码做了你想做的事情。重点是将Fortran类型绑定到C,并且当在C端声明指针时声明一个
c_ptr
。编制:
umuewwlo2#
我的解决方案。
C++代码:
Fortran代码: