Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Reply to Dr. Steve

Zhanghong_T_
Novice
214 Views

In the interface, replace "type(c_ptr), value" with "character, dimension(*)". In the call, simply remove the C_LOC or LOC.

------

 

Dear Dr. Steve,

 

Thank you very much for your kindly reply. Your answer solved the function I given before. But there are many different data type need to pass between C++ and Fortran. For example, the following is another C++ function called by Fortran:

C++ definition:

extern "C" void CreateCylinder5(myobj *object, int nfixed, double *fixedangle,int *onplane, double *cyltheta, double threshold, int ncyl, int slices, double *allholeangle, int nhole, double rad, double *upcenter, double *bottomcenter, outputobj *out) ;

my original Fortran interface:

  subroutine CreateCylinder5(object,nfixed,fixedangle,onplane,theta,threshold,ntheta,slices,allholeangle,nhole,rad,upcenter,bottomcenter,out) bind(c,name='CreateCylinder5')
  use iso_c_binding
  implicit none
  type(c_ptr),value::object,fixedangle,onplane,theta,allholeangle,upcenter,bottomcenter,out
  integer(c_int),value::nfixed,ntheta,slices,nhole
  real(c_double),value::rad,threshold
  end subroutine

and the calling of the function:

call CreateCylinder5(c_loc(wellobj),ncollapseangle,c_loc(collapseangle),c_loc(onplane),c_loc(tmpangle),dtheta,ntmpangle,nangle, c_loc(hole(1,1:nhole)),nhole,radius1, c_loc(upcenter0), c_loc(bottomcenter0), c_loc(outputwellobj))

How to modify this kind of code?

 

On the other hand, is it mean that I have to modify the code one by one?

 

Thanks,

Tang Laoya

0 Kudos
2 Replies
jimdempseyatthecove
Black Belt
187 Views

Fortran, by default, passes arguments by reference (pointer).

! extern "C" void CreateCylinder5(
!     myobj *object,
!     int nfixed,
!     double *fixedangle,
!     int *onplane,
!     double *cyltheta,
!     double threshold,
!     int ncyl,
!     int slices,
!     double *allholeangle,
!     int nhole,
!     double rad,
!     double *upcenter,
!     double *bottomcenter,
!     outputobj *out) ;
interface
  subroutine CreateCylinder5(object,nfixed,fixedangle,onplane,theta,threshold,ntheta,slices,allholeangle,nhole,rad,upcenter,bottomcenter,out) bind(c,name='CreateCylinder5')
  use iso_c_binding
  implicit none
!     myobj *object,
  type(myobj_t) :: object
!     int nfixed,
  integer(c_int), value :: nfixed
!     double *fixedangle,
  real(c_double) :: fixedangle(3) ! I am assuming X, Y, Z
!     int *onplane,
  real(c_double) :: onplane(3)
!     double *cyltheta,
  real(c_double) :: cyltheta(3)
!     double threshold,
  real(c_double), value :: threshold
!     int ncyl,
  integer(c_int), value :: ncyl
!     int slices,
  integer(c_int), value :: slices
!     double *allholeangle,
  real(c_double) :: allholeangle(nhole)
!     int nhole,
  integer(c_int), value :: nhole
!     double rad,
  real(c_double),value :: rad
!     double *upcenter,
  real(c_double) :: upcenter(3)
!     double *bottomcenter,
  real(c_double) :: bottomcenter(3)
!     outputobj *out) ;
  real(c_double) :: out(1:*) ! **** the * bound may be known?
  end subroutine
end interface

Call:

call CreateCylinder5(wellobj,ncollapseangle,collapseangle,onplane,tmpangle,dtheta,ntmpangle,nangle, hole(1,1:nhole),nhole,radius1, upcenter0, bottomcenter0, outputwellobj)

Jim Dempsey

Steve_Lionel
Black Belt Retired Employee
184 Views

Unfortunately, you made all this work for yourself when you chose to declare these procedures to accept a C_PTR by value - as Jim points out, Fortran passes arguments by address normally (guaranteed when BIND(C) is used.) 

Reply