簡體   English   中英

綁定C ++和Fortran

[英]Binding C++ and Fortran

我想將C ++和Fortran結合在一起。 我的Fortran代碼將使用C ++函數,而C ++函數將更改Fortran的變量並將其發送回去。 C ++函數是用其他C ++代碼構建的,例如C ++函數將使用其他.cpp文件中的某些子函數。 我使用ifort制作了Fortran代碼,並將C ++函數作為一個目標文件test.o添加到了我的Fortran生成文件中。 我還將每個需要的C ++ .o文件(支持test.o)放在makefile中。 顯示錯誤

#6633,“實際參數的類型與虛擬參數的類型不同”。

這是代碼。

Fortran代碼

  use, intrinsic :: ISO_C_BINDING, only: C_INT, C_DOUBLE   
  implicit double precision(a-h,o-z),integer(i-n)
  Interface
   integer (C_INT) function SolveBIE_(x, y, aa, m) BIND(C, NAME='SolveBIE_')
   use, intrinsic :: ISO_C_BINDING
   implicit none
   type (C_PTR), value :: x
   type (C_PTR), value :: y
   type (C_PTR), value :: aa
   integer (C_INT), value :: m
   end function SolveBIE_
  end Interface
  integer (C_INT) :: m
  real (C_DOUBLE), ALLOCATABLE, DIMENSION(:,:), target :: x
  real (C_DOUBLE), ALLOCATABLE, DIMENSION(:,:), target :: y
  real (C_DOUBLE), ALLOCATABLE, DIMENSION(:,:), target :: aa
  ALLOCATE(x(0:MAXLEN,MAXINTERFACES))
  ALLOCATE(y(0:MAXLEN,MAXINTERFACES))
  ALLOCATE(aa(0:MAXLEN,MAXINTERFACES))

我的Fortran代碼運行

  mm = SolveBIE_(x(1,1),y(1,1),aa(1,1),m) 

使用C ++代碼以及錯誤的出處是在x, y, aa我使用x(1,1)而不是x ,因為如果使用x ,那么還會有另一個錯誤

#6634,“違反了實際參數和虛擬參數的形狀匹配規則”

我不明白為什么它應該是x(1,1) 為什么這樣做有效,而不是x

我的C ++代碼

  #ifdef __cplusplus
  extern "C" {
  #endif
  int solveBIE_(double *ini_bdry_x, double *ini_bdry_y, double *ini_bdry_um, int *fM)
{  
     double(*bdry_node)[2] = new double[M1][2];
     for (int k = 0; k < M; k++) {
        bdry_node[k+1][0] = ini_bdry_x[k+1];
        bdry_node[k+1][1] = ini_bdry_y[k+1];
        bdry_theta[k+1] = Atan(ini_bdry_x[k+1], ini_bdry_y[k+1]);}

    ... some functions in other .cpp file

編寫接口的方式,您必須構造一個C_PTR來數組x並將其作為第一個參數傳遞:

use, intrinsic :: ISO_C_BINDING, only: C_INT, C_DOUBLE, C_PTR, C_LOC
! ...
type(C_PTR) PTRx
! ...
PTRx = C_LOC(x(LBOUND(x,1),LBOUND(x,2)))
! ...
mm = solveBIE_(PTRx, PTRy, PTRaa, m)

如上所示,您還必須修復接下來的兩個參數。 但是您需要重寫參數fM的接口,因為就目前情況而言,Fortran將按值傳遞整數,而C ++則期望使用指針。 鑒於此,我將使用在C ++函數中為參數指定的名稱並通過引用傳遞所有內容來完全重寫接口。 偽參數的名稱可能在Fortran中可見,因此使它們有意義是很有用的。 在下文中,我假設fM指向被調用者中的標量:

  Interface
   function SolveBIE_(ini_bdry_x, ini_bdry_y, ini_bdry_um, fM) &
      BIND(C, NAME='SolveBIE_')
   import
   implicit none
   integer(C_INT) SolveBIE_
   real(C_DOUBLE) :: ini_bdry_x(*)
   real(C_DOUBLE) :: ini_bdry_y(*)
   real(C_DOUBLE) :: ini_bdry_um(*)
   integer (C_INT) :: fM
   end function SolveBIE_
  end Interface

然后,您以后可以正常地或多或少地調用它

mm = SolveBIE_(x,y,aa,m)

注意x(1,1)是錯誤的,因為LBOUND(x,1) = 0 ,而不是1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM