Fortran Coder

查看: 23166|回复: 11
打印 上一主题 下一主题

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

[复制链接]

238

帖子

0

主题

0

精华

版主

World Analyser

F 币
642 元
贡献
470 点

新人勋章美女勋章元老勋章热心勋章规矩勋章管理勋章

QQ
楼主
发表于 2017-7-12 21:03:45 | 显示全部楼层
1. 我的代码是通用代码。不分动态库,静态库。
2. 用静态库的话,fortran编译得到obj或lib文件,加入C++的项目即可。
3. 用动态库的话,对于 Intel Fortran,需要加一句 !DEC$ ATTRIBUTES  DLLEXPORT  ::   cylindermeshing
4. 动态库可以有隐式调用和显式调用两种用法。这是 VC++ 的事情。我这里的代码适合隐式调用。
回复

使用道具 举报

238

帖子

0

主题

0

精华

版主

World Analyser

F 币
642 元
贡献
470 点

新人勋章美女勋章元老勋章热心勋章规矩勋章管理勋章

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

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

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

[C++] 纯文本查看 复制代码
#include <iostream>

struct singleinfo{
  int controlno;
  int unittype;
  int solid;
  double coearea;
  double volume;
  double center[3];
  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[0] = 11;
  cylinderinfo.center[1] = 11;
  cylinderinfo.center[2] = 11;
  cylindermeshing(r, h, &cylinderinfo);
  double deta[3][3];
  for (int i = 0; i < 3; i++){
    for (int j = 0; j < 3; j++){
      deta[j][i] = j*4 + i;
    }
  }
  cout << thirddet( &deta[0][0] );
}

[Fortran] 纯文本查看 复制代码
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
回复

使用道具 举报

238

帖子

0

主题

0

精华

版主

World Analyser

F 币
642 元
贡献
470 点

新人勋章美女勋章元老勋章热心勋章规矩勋章管理勋章

QQ
板凳
发表于 2017-7-13 22:30:51 | 显示全部楼层
cfortran 发表于 2017-7-13 15:58
链接时出现错误error LNK1104:无法打开文件‘ifconsol.lib’
我在附加依赖项中添加ifconsol.lib后还是不 ...

在ivf安装目录下找到ifconsol.lib
并且记下它的路径(复制)

然后在vs的工程属性“库目录”里,粘贴上这个路径。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-5-6 09:26

Powered by Tencent X3.4

© 2013-2024 Tencent

快速回复 返回顶部 返回列表