Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner

A question about Fortran call C

Hello, Recently I do some work using Fortran call C, but it failed. I want to ask you a question, for example: "real(c_double)",it means "real" in Fortran, "double" in C. And I want use Fortran to call C API, "void C_SOCP( double c[], MSKboundkeye bkc[] )". Therefore "c" can be recognized using "real(c_double)" in Fortran, but I don't know how to deal with " MSKboundkeye bkc[] ". Here," MSKboundkeye bkc[] " was typedef in C, it was shown as follows: typedef enum MSKboundkey_enum MSKboundkeye; MSKrescodee (MSKAPI MSK_putconbound) ( MSKtask_t task, MSKint32t i, MSKboundkeye bk, MSKrealt bl, MSKrealt bu); Do you know how to solve the problem?
0 Kudos
3 Replies
Highlighted
Beginner

Hello,

Hello,
Recently I do some work using Fortran call C, but it failed. I want to ask you a question, for example: "real(c_double)",it means "real" in Fortran, "double" in C. And I want use Fortran to call C API, "void C_SOCP( double c[], MSKboundkeye bkc[] )". Therefore "c" can be recognized using "real(c_double)" in Fortran, but I don't know how to deal with " MSKboundkeye bkc[] ". Here," MSKboundkeye bkc[] " was typedef in C, it was shown as follows:
typedef enum MSKboundkey_enum MSKboundkeye;
MSKrescodee (MSKAPI MSK_putconbound) (
MSKtask_t task,
MSKint32t i,
MSKboundkeye bk,
MSKrealt bl,
MSKrealt bu);

Do you know how to solve the problem?

0 Kudos
Highlighted
New Contributor I

Maybe U should accomplish the

Maybe U should accomplish the struct in Fortran derived type ways somehow and then use type pointer as dummy argument.

0 Kudos
Highlighted
Black Belt

You can define C compatible

You can define C compatible enumerations in Fortran using an enum construct.  This construct is an alternative way of defining integer named constants, the kind of which will be C compatible with the integer type used in C for the enumeration.  You can determine which kind is used by using the Fortran KIND intrinsic on an individual enumerator, chances are the kind will be the same as C_INT. 

Your C function then takes an array of those enumerators.

This code fragment may help to illustrate.

ENUM, BIND(C)
  ENUMERATOR :: MSK_BK_BEGIN = 0
  ENUMERATOR :: MSK_BK_END = 5
  ENUMERATOR :: MSK_BK_LO = 0
  ENUMERATOR :: MSK_BK_UP = 1
  ENUMERATOR :: MSK_BK_FX = 2
  ENUMERATOR :: MSK_BK_FR = 3
  ENUMERATOR :: MSK_BK_RA = 4
END ENUM

INTEGER, PARAMETER :: MSKboundkeye = KIND(MSK_BK_BEGIN)

INTERFACE
  SUBROUTINE C_SOCP(c, bkc) BIND(C, NAME='C_SOCP')
    USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_DOUBLE
    IMPORT :: MSKboundkeye
    IMPLICIT NONE
    REAL(C_DOUBLE) :: c(*)
    INTEGER(MSKboundkeye) :: bkc(*)
  END SUBROUTINE C_SOCP
END INTERFACE

REAL(C_DOUBLE) :: local_c(2)
INTEGER(MSKboundkeye) :: local_bkc(2)

local_c = [ 1.0, 2.0 ]
local_bkc = [ MSK_BK_LO, MSK_BK_UP ]
CALL C_SOCP(local_c, local_bkc)

 

0 Kudos