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
Post a Comment