cfortran 发表于 2017-7-12 21:03:44

C++与fortran混编 subroutine和function在module里

先贴代码:
module hydromodelUtil
implicit none
double precision, parameter :: pi=3.141593d0
type singleinfo
    integer :: controlno
    integer :: unittype
    integer :: solid
    double precision :: coearea
    double precision :: volume
    double precision, dimension(3) :: center
    integer :: pointcount, trianglecount
    double precision, dimension(:,:), allocatable :: pointchain
    double precision, dimension(:,:,:), allocatable :: trianglechain
end type singleinfo
contains
subroutine cylindermeshing(r, h, cylinderinfo)
    implicit none
    double precision :: r, h
    type(singleinfo) :: cylinderinfo
    integer :: polyedge=60
    double precision, dimension(:,:), allocatable :: point
    double precision :: dtheta
    integer :: 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) )

    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

function thirddet(deta)
    double precision, dimension(3,3) :: deta
    double precision :: thirddet
    thirddet=deta(1,1)*(deta(2,2)*deta(3,3)-deta(3,2)*deta(2,3)) &
      & -deta(2,1)*(deta(1,2)*deta(3,3)-deta(3,2)*deta(1,3)) &
      & +deta(3,1)*(deta(1,2)*deta(2,3)-deta(2,2)*deta(1,3))
end function thirddet

end module hydromodelUtil
请问怎么才能让c++调用生成的dll 里面的子程序和函数啊   我自己改的程序老是出现各种莫名奇妙的错误,拜求大神给看看,多谢了

kyra 发表于 2017-7-12 21:03:45

1. 我的代码是通用代码。不分动态库,静态库。
2. 用静态库的话,fortran编译得到obj或lib文件,加入C++的项目即可。
3. 用动态库的话,对于 Intel Fortran,需要加一句 !DEC$ ATTRIBUTESDLLEXPORT::   cylindermeshing
4. 动态库可以有隐式调用和显式调用两种用法。这是 VC++ 的事情。我这里的代码适合隐式调用。

kyra 发表于 2017-7-13 07:51:07

module中的函数,和普通的外部函数一样的。直接写 Bind( C , Name ) 就可以了。
你目前的设计,最难的地方在于,你要在 type singleinfo 结构中包含 allocatable 的数组 pointchain ,这是比较困难的。
这一实现,由于fortran和C均没有标准的底层实现。所以标准的混编也就无法实现。

一般的做法是,把allocatable数组单独放在外面当做另外的参数进行传递。fortran不必关心它在C++里是静态的还是动态分配的。

排除这几个数组之外,我写了一个范例给你:

#include <iostream>

struct singleinfo{
int controlno;
int unittype;
int solid;
double coearea;
double volume;
double center;
int pointcount , trianglecount;
};

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 << thirddet( &deta );
}
module hydromodelUtil
implicit none
double precision, parameter :: pi=3.141593d0
type , Bind( C ) :: singleinfo
    integer :: controlno
    integer :: unittype
    integer :: solid
    double precision :: coearea
    double precision :: volume
    double precision, dimension(3) :: center
    integer :: pointcount, trianglecount
end type singleinfo
contains
subroutine cylindermeshing(r, h, cylinderinfo) Bind(C,Name="cylindermeshing")
    implicit none
    double precision :: r, h
    type(singleinfo) :: cylinderinfo
    write(*,*) r , h , cylinderinfo
end subroutine cylindermeshing

function thirddet(deta) Bind( C , Name = "thirddet" )
    double precision, dimension(3,3) :: deta
    double precision :: thirddet
    thirddet=deta(1,1)*(deta(2,2)*deta(3,3)-deta(3,2)*deta(2,3)) &
      & -deta(2,1)*(deta(1,2)*deta(3,3)-deta(3,2)*deta(1,3)) &
      & +deta(3,1)*(deta(1,2)*deta(2,3)-deta(2,2)*deta(1,3))
end function thirddet

end module hydromodelUtil

cfortran 发表于 2017-7-13 14:14:06

本帖最后由 cfortran 于 2017-7-13 14:17 编辑

我看你的代码里没有加载动态链接库的代码,现在这样做是不需要做成动态链接库 而采用直接链接的方式混编吗   我用的是ifc的平台   看网上直接混编有个实例是用gfc平台做的。在VS里面具体该怎么做啊这是网上那个gfc平台做的

cfortran 发表于 2017-7-13 14:24:34

kyra 发表于 2017-7-13 07:51
module中的函数,和普通的外部函数一样的。直接写 Bind( C , Name ) 就可以了。
你目前的设计,最难的地方 ...

我看你的代码里没有加载动态链接库的代码,现在这样做是不需要做成动态链接库 而采用直接链接的方式混编吗   我用的是ifc的平台   看网上直接混编有个实例是用gfc平台做的。在VS里面具体该怎么做啊 ?这是网上那个gfc平台做的http://bbs.fcode.cn/forum.php?mod=image&aid=1526&size=300x300&key=075a5464c2ed1b7a&nocache=yes&type=fixnone

cfortran 发表于 2017-7-13 15:21:13

kyra 发表于 2017-7-12 21:03
1. 我的代码是通用代码。不分动态库,静态库。
2. 用静态库的话,fortran编译得到obj或lib文件,加入C++的 ...

嗯多谢了    我再试试

cfortran 发表于 2017-7-13 15:58:32

kyra 发表于 2017-7-12 21:03
1. 我的代码是通用代码。不分动态库,静态库。
2. 用静态库的话,fortran编译得到obj或lib文件,加入C++的 ...

链接时出现错误error LNK1104:无法打开文件‘ifconsol.lib’
我在附加依赖项中添加ifconsol.lib后还是不行。请问这个怎么解决   

ps:我已经把fortran编译得到的source1.obj文件添加到了C++的项目里了

pasuka 发表于 2017-7-13 16:02:20

本帖最后由 pasuka 于 2017-7-13 16:03 编辑

为啥不能先看看ivf帮助文档和范例呢?
Intel® Fortran Compiler XE 12.1 User and Reference GuidesMixed Language ProgrammingParent topic: Compiler Reference


[*]Programming with Mixed Languages Overview
[*]Calling Subprograms from the Main Program
[*]Summary of Mixed-Language Issues
[*]Adjusting Calling Conventions in Mixed-Language Programming
[*]Adjusting Naming Conventions in Mixed-Language Programming
[*]Prototyping a Procedure in Fortran
[*]Exchanging and Accessing Data in Mixed-Language Programming
[*]Handling Data Types in Mixed-Language Programming
[*]Intel(R) Fortran/C Mixed-Language Programs

http://scc.ustc.edu.cn/zlsc/sugo ... /main_for/index.htm

cfortran 发表于 2017-7-13 16:19:30

pasuka 发表于 2017-7-13 16:02
为啥不能先看看ivf帮助文档和范例呢?
Intel® Fortran Compiler XE 12.1 User and Reference GuidesMixed...

嗯也在看modern fortran explained 这本书上的介绍   无奈英语渣的不行   只能一个词一个词的查。。。。。。

pasuka 发表于 2017-7-13 16:22:47

cfortran 发表于 2017-7-13 16:19
嗯也在看modern fortran explained 这本书上的介绍   无奈英语渣的不行   只能一个词一个词的查。。。 ...

ivf帮助文档啃不动,ivf自带的sample 代码总归看得懂吧?!
页: [1] 2
查看完整版本: C++与fortran混编 subroutine和function在module里