binding - How to bind C's char** argument in Fortran? -


i need bind c function in fortran. c function's prototype like

/* if argv[i] null, length of argv[] */ int foo(char* argv[]); 

i want call foo in fortran subroutine bar

! if argv(i) blank string, length of argv. ! constant max_string_len maximal length of possible element in argv. subroutine bar(argv)    character(len=*), intent(in) :: argv(*)    character(kind=c_char), dimension(*), allocatable :: argv_c(*) !???    ! convert argv argv_c element element,   ! allocate(argv_c(len_trim(argv(i)) + 1) ! plus 1 put c_null_char   ! assign argv(i) argv_c(i)    ierror = foo(argv_c)   ! deallocate each argv_c(i) end subroutine bar 

i want know how declare prototype foo. designed one, not sure if correct. argv interoperable char**?

function foo(argv) bind(c, name="foo")     character(kind=c_char), dimension(*), intent(in) :: argv(*) end function 

the c declaration char *argv[] array of pointer char. equivalent fortran argument declaration type(c_ptr) :: argv(*), each element in array c address of character of c kind.

the usual c convention character first character in array of character (i.e. have c address of array of character of c kind), , length of array of char null terminated (i.e. have array of pointers c strings). comment in c code indicates size of array of pointers indicated final array element of null. consistent conventions around argv arguments in c.

to able find c address of object in fortran, object must have target attribute. results of evaluating expression not have target attribute.

as written, bar subroutine has no idea size of argv dummy array (it assumed size argument). however, if argv dummy argument perhaps assumed shape, like:

subroutine bar(argv)   use, intrinsic :: iso_c_binding, only: c_loc, c_char, c_int,  &       c_null_char, c_null_ptr   ! input bar (?) needs converted use in c function.   character(*), intent(in) :: argv(:)   ! array of c pointers.   type(c_ptr) :: argv_c(size(argv) + 1)   ! local type simplify memory management.   type string     character(len=:,kind=c_char), allocatable :: item   end type string   ! temporary arrays of character.  need have target c_loc.   type(string), target :: tmp(size(argv))   ! utility index.   integer ::                        ! interface c function   interface     function foo(argv) bind(c, name='foo')       use, intrinsic :: iso_c_binding, only: c_ptr, c_int       implicit none       ! intent(in) here assuming foo doesn't modify array of pointers.       type(c_ptr), intent(in) :: argv(*)       integer(c_int) :: foo     end function foo   end interface    integer(c_int) :: ierror    = 1, size(argv)     ! may involve kind conversion.     tmp(i)%item = trim(argv(i)) // c_null_char     argv_c(i) = c_loc(tmp(i)%item)   end   ! size of argv array on c side indicated null.   argv_c(size(argv_c)) = c_null_ptr    ierror = foo(argv_c)   ...    ! memory allocated components of tmp object (and hence    ! things pointed @ argv_c array) go away when    ! subroutine terminates. end subroutine bar 

Comments

Popular posts from this blog

android - Get AccessToken using signpost OAuth without opening a browser (Two legged Oauth) -

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: mockito -

google shop client API returns 400 bad request error while adding an item -