C++与Fortran混编 type里值的传递和allocate相关的问题
先贴代码:module hydromodelUtil
use iso_c_binding
implicit none
double precision, parameter :: pi=3.141593d0
!这部分为输入值
type ,Bind(C)::unitinfo
integer(c_int) :: controlno
character(c_char) :: unitname
integer(c_int) :: unittype
integer(c_int) :: solid
real (c_double):: coearea
real(c_double) ,dimension(3) :: shapepara
integer(c_int):: pn=0
double precision, dimension(:,:), allocatable :: plist
real(c_double), dimension(3) :: rotationpara, tranpara
end type unitinfo
!这部分为输出值
type ,Bind(C):: singleinfo
integer(c_int) :: controlno
integer(c_int) :: unittype
integer(c_int) :: solid
real(c_double) :: coearea
real(c_double):: volume
real(c_double), dimension(3) :: center
integer (c_int):: pointcount, trianglecount
double precision, dimension(:,:), allocatable :: pointchain
double precision, dimension(:,:,:), allocatable :: trianglechain
end type singleinfo
contains
subroutine cylindermeshing(r, h, cylinderinfo) Bind(C,Name="cylindermeshing")
!DEC$ ATTRIBUTES DLLEXPORT::cylindermeshing
implicit none
real(c_double) :: r, h
type(singleinfo) :: cylinderinfo
integer(c_int) :: polyedge=60
double precision, dimension(:,:), allocatable :: point
real(c_double) :: dtheta
integer(c_int) :: meshi
dtheta=2*pi/real(polyedge)
cylinderinfo%volume=(0.5d0*polyedge*sin(dtheta)*r**2)*h
cylinderinfo%center=(/ 0.0d0, 0.0d0, 0.5d0*h /)
cylinderinfo%pointcount=2*polyedge
cylinderinfo%trianglecount=4*polyedge
allocate(point(2,polyedge+1) )
allocate(cylinderinfo%pointchain(3,cylinderinfo%pointcount) )
do meshi=1, polyedge, 1
point(1,meshi)=r*cos( (real(meshi)-1.0d0)*dtheta)
point(2,meshi)=r*sin( (real(meshi)-1.0d0)*dtheta)
end do
point(:, polyedge+1)=point(:, 1)
do meshi=1, polyedge, 1
cylinderinfo%pointchain(1:2,meshi)=point(1:2,meshi)
cylinderinfo%pointchain(3,meshi)=0.0d0
cylinderinfo%pointchain(1:2,polyedge+meshi)=point(1:2,meshi)
cylinderinfo%pointchain(3,polyedge+meshi)=h
end do
end subroutine cylindermeshing
end module hydromodelUtil
代码太长,粘了一部分,但主题就是这些,其他大同小异。我是要在C++中以显式调用动态库的方法实现混编的,这里面有两个问题
1、type中的值不知道怎么传递,比如这行代码cylinderinfo%volume=(0.5d0*polyedge*sin(dtheta)*r**2)*h 怎么处理
2、allocate这个怎么处理 这里我有一个很笨的想法 就是给分配的数据定一个极值,就是说把大小定为常量,但是不知道后续计算时会不会产生什么不良的后果
由于Fortran和C++都是刚学不久,问的问题可能很幼稚,见笑了
导师任务时间上要的太紧,系统的学习可能来不及了,拜求大神帮帮我 ,给提供一下思路。多谢了
在 Fortran 语言里。pointchain 大小是 1:3 * 1:cylinderinfo%pointcount
则 C 语言中正好相反,所以应该视为 0:cylinderinfo%pointcount-1 * 0:2
因此 fortran 中 pointchain(2,6) = 381 ,则 C 中应该输出 cout << cylinderinfo.pointchain[ (6-1)*3+(2-1) ] 本帖最后由 kyra 于 2017-7-14 08:20 编辑
问题1,无需额外处理。
问题2,不能在type里存放fortran语言的动态分配数组。否则C语言无法用标准化的手段访问。解决办法是,用 C 指针,fortran分配后把地址赋给 C 指针。具体看注释
(这方法适合于fortran的动态分配返回给 C,并不适合 C 分配的数组传递给 fortran)
module hydromodelUtil
use iso_c_binding
implicit none
double precision, parameter :: pi=acos(-1.d0)
!这部分为输出值
type ,Bind(C):: singleinfo
integer(c_int) :: controlno
integer(c_int) :: unittype
integer(c_int) :: solid
real(c_double) :: coearea
real(c_double):: volume
real(c_double), dimension(3) :: center
integer (c_int):: pointcount, trianglecount
type(C_PTR) :: pointchain , trianglechain!!!!!!!用C指针
end type singleinfo
contains
subroutine cylindermeshing(r, h, cylinderinfo) Bind(C,Name="cylindermeshing")
!DEC$ ATTRIBUTES DLLEXPORT::cylindermeshing
implicit none
real(c_double) :: r, h
type(singleinfo) :: cylinderinfo
integer(c_int) :: polyedge=60
double precision, dimension(:,:), allocatable :: point
double precision, dimension(:,:), allocatable , target ,save :: pointchain!!!!!!!Fortran分配数组
real(c_double) :: dtheta
integer(c_int) :: meshi
dtheta=2*pi/real(polyedge)
cylinderinfo%volume=(0.5d0*polyedge*sin(dtheta)*r**2)*h
cylinderinfo%center=(/ 0.0d0, 0.0d0, 0.5d0*h /)
cylinderinfo%pointcount=2*polyedge
cylinderinfo%trianglecount=4*polyedge
allocate(point(2,polyedge+1) )
allocate(pointchain(3,cylinderinfo%pointcount) )!!!!!!!
do meshi=1, polyedge, 1
point(1,meshi)=r*cos( (real(meshi)-1.0d0)*dtheta)
point(2,meshi)=r*sin( (real(meshi)-1.0d0)*dtheta)
end do
point(:, polyedge+1)=point(:, 1)
do meshi=1, polyedge, 1
pointchain(1:2,meshi)=point(1:2,meshi)
pointchain(3,meshi)=0.0d0
pointchain(1:2,polyedge+meshi)=point(1:2,meshi)
pointchain(3,polyedge+meshi)=h
end do
cylinderinfo%pointchain = c_loc( pointchain )!!!!!!!把地址给C指针
end subroutine cylindermeshing
end module hydromodelUtil
#include <iostream>
struct singleinfo{
int controlno;
int unittype;
int solid;
double coearea;
double volume;
double center;
int pointcount , trianglecount;
double *pointchain , *trianglechain;/////// C 指针
};
extern "C" {
void cylindermeshing( double & , double & , struct singleinfo *);
double thirddet( double * );
}
using namespace std;
int main()
{
struct singleinfo cylinderinfo;
double r = 3.0;
double h = 4.0;
cylinderinfo.controlno= 1;
cylinderinfo.unittype = 2;
cylinderinfo.solid = 3;
cylinderinfo.coearea = 4;
cylinderinfo.volume = 5;
cylinderinfo.unittype = 6;
cylinderinfo.pointcount = 7;
cylinderinfo.trianglecount = 8;
cylinderinfo.center = 11;
cylinderinfo.center = 11;
cylinderinfo.center = 11;
cylindermeshing(r, h, &cylinderinfo);
double deta;
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
deta = j*4 + i;
}
}
cout << cylinderinfo.pointchain << endl;
}
kyra 发表于 2017-7-14 08:12
问题1,无需额外处理。
问题2,不能在type里存放fortran语言的动态分配数组。否则C语言无法用标准化的手段 ...
这里最后一行代码,假如想输出cout<<cylinderinfo.pointchain<<endl;传递过来的数据,该怎么处理啊我试了一下传递过来的数据明显不对啊 kyra 发表于 2017-7-14 15:54
在 Fortran 语言里。pointchain 大小是 1:3 * 1:cylinderinfo%pointcount
则 C 语言中正好相反,所以应该视 ...
真的是这样啊。。。数据都对,好厉害。
我这个程序其实是一个中间程序,是一个划分网格的程序,也就是说这里面的所有数据都需要导出来
这样看来我需要再做一个函数进行转化一下对吗
顺便问一下这个数据转换有相关的资料吗 我想学习一下 不需要转换。使用的时候注意顺序即可。 kyra 发表于 2017-7-13 19:42
在 Fortran 语言里。pointchain 大小是 1:3 * 1:cylinderinfo%pointcount
则 C 语言中正好相反,所以应该视 ...
重复调用这样处理的dll中的函数,发生这样的错误怎么办http://bbs.fcode.cn/forum.php?mod=image&aid=1533&size=300x300&key=555826707c687f38&nocache=yes&type=fixnone
allocatable array is already allocated 动态分配的数组已经被分配过了
有没有什么办法能解决这个,是不是刚开始这里
real(c_double),dimension(:,:),allocatable,target,save::point
少了什么参数啊?
你需要在合适的时机,释放 pointchain 数组。
页:
[1]