我需要在 Fortran 中绑定(bind)一个 C 函数。 C 函数的原型(prototype)类似于
/* If argv[i] is NULL, then i is the length of argv[] */
int foo(char* argv[]);
我想在 Fortran 子程序 bar 中调用 foo
! If argv(i) is a blank string, then i is the length of argv.
! Constant MAX_STRING_LEN is the maximal length of any possible element in argv.
subroutine bar(argv)
character(len=*), intent(in) :: argv(*)
character(kind=c_char), dimension(*), allocatable :: argv_c(*) !???
! convert argv to argv_c element by element, something like
! allocate(argv_c(len_trim(argv(i)) + 1) ! Plus 1 to put C_NULL_CHAR
! assign argv(i) to argv_c(i)
ierror = foo(argv_c)
! deallocate each argv_c(i)
end subroutine bar
我想知道如何声明 foo 的原型(prototype)。我设计了这个,但我不确定它是否正确。这个 argv 可以与 char** 互操作吗?
function foo(argv) bind(c, name="foo")
character(kind=c_char), dimension(*), intent(in) :: argv(*)
end function
类似问答:Creating a FORTRAN interface to a C function that returns a char*在那里有点难以定位(至少对我而言)。
你必须传递指向数组的指针,因为 char**
function foo(argv) bind(c, name="foo")
type(c_ptr) :: argv !note no `value` here
! what is the `intent` to put here?
end function
普通的数组参数只会传递一个你不想要的 char*
。
第一次尝试:
ierror = foo(c_loc(argv_c))
如果 C 部分没有分配它,上面的方法就可以工作,它可能会分配。接下来的问题是获取字符串的长度。
type(c_ptr) :: argv_c_ptr
character(kind=c_char),pointer :: argv_c(:)
ierror = foo(argv_c_ptr)
现在您必须找出数组的长度,我将调用 C 过程 strlen(请参阅 http://fortranwiki.org/fortran/show/c_interface_module 中的 C_strlen)。之后你可以调用:
call c_f_pointer(argv_c_ptr, argv_c, [len])
不要忘记正确释放 C 分配的字符串,不要为此使用 Fortran `deallocate。
我是一名优秀的程序员,十分优秀!