如何通过iso_C_绑定从Fortran调用的C函数接收字符串?
我想从Fortran中调用一个C函数,并接收C函数中定义的字符串。我搜索了一下,但到目前为止,我找不到一个有效的、直截了当的答案 实际上,我已经找到了一个解决方法:接收一个字符数组,然后使用内在函数如何通过iso_C_绑定从Fortran调用的C函数接收字符串?,c,string,fortran,fortran-iso-c-binding,C,String,Fortran,Fortran Iso C Binding,我想从Fortran中调用一个C函数,并接收C函数中定义的字符串。我搜索了一下,但到目前为止,我找不到一个有效的、直截了当的答案 实际上,我已经找到了一个解决方法:接收一个字符数组,然后使用内在函数transfer将结果放入Fortran字符串中。 这是我的工作代码 Fortran主程序: program pr implicit none character(200) :: stringa call strfromc(stringa) write (6,*) '
transfer
将结果放入Fortran字符串中。
这是我的工作代码
Fortran主程序:
program pr
implicit none
character(200) :: stringa
call strfromc(stringa)
write (6,*) 'FPR stringa: "', trim(stringa),'"'
stop
end program pr
program pr
use sfc
implicit none
character(200) :: stringa
call strfromc(stringa)
write (6,*) 'FPR stringa: "', trim(stringa),'"'
stop
end program pr
Fortran子程序:
subroutine strfromc(stringa)
use iso_c_binding
implicit none
character(200) :: stringa
interface
subroutine getstrfromc(ld,d) bind(c,name='getString')
import :: c_int, c_ptr
integer(c_int) :: ld
type(c_ptr), value :: d
end subroutine getstrfromc
end interface
! declare a character array of type c_char and sufficient length:
character(c_char), dimension(200), target :: d1
integer :: ld1 ! will contain the string length
integer :: i
! the C pointer of character array d1 is passed:
call getstrfromc(ld1, c_loc(d1))
! read the first ld1 elements of array d1 as a character string, which will be returned:
stringa= transfer(d1(1:ld1), stringa)
write (6,*) 'SF d1: ', (d1(i),i=1,ld1)
write (6,*) 'SF stringa: "', trim(stringa),'"'
write (6,*) ''
return
end subroutine
module sfc
use iso_c_binding
implicit none
interface
subroutine getstrfromc(ld,d) bind(c,name='getString')
import :: c_int, c_ptr
integer(c_int) :: ld
type(c_ptr), value :: d
end subroutine getstrfromc
end interface
contains
subroutine strfromc(d1)
use iso_c_binding
implicit none
! declare a character array of type c_char and sufficient length:
character(c_char), dimension(200), target :: d1
integer :: ld1 ! will contain the string length
integer :: i
! the C pointer of character array d1 is passed:
call getstrfromc(ld1, c_loc(d1))
! clean elements after the ld1-th:
d1(ld1+1:)= ''
write (6,*) 'SF d1: ', (d1(i),i=1,ld1)
write (6,*) ''
return
end subroutine
end module sfc
C功能:
#include <stdio.h>
#include <string.h>
void getString(int * lw, char * w) {
printf("Enter a string:\n");
scanf("%[^\n]", w); //scanning the whole string, including the white spaces
*lw= strlen(w);
printf("C: w: %s\n", w);
printf("C: lw: %d\n", *lw);
printf("\n");
return;
}
#包括
#包括
void getString(int*lw,char*w){
printf(“输入字符串:\n”);
scanf(“%[^\n]”,w);//扫描整个字符串,包括空格
*lw=斯特伦(w);
printf(“C:w:%s\n”,w);
printf(“C:lw:%d\n”,*lw);
printf(“\n”);
返回;
}
有人能给我一个更直接的建议吗?我把它贴在一个答案里,因为它看起来更干净。 这是我根据@francescalus的建议修改的代码 Fortran主程序:
program pr
implicit none
character(200) :: stringa
call strfromc(stringa)
write (6,*) 'FPR stringa: "', trim(stringa),'"'
stop
end program pr
program pr
use sfc
implicit none
character(200) :: stringa
call strfromc(stringa)
write (6,*) 'FPR stringa: "', trim(stringa),'"'
stop
end program pr
Fortran模块,包括与C函数和Fortran子程序的接口:
subroutine strfromc(stringa)
use iso_c_binding
implicit none
character(200) :: stringa
interface
subroutine getstrfromc(ld,d) bind(c,name='getString')
import :: c_int, c_ptr
integer(c_int) :: ld
type(c_ptr), value :: d
end subroutine getstrfromc
end interface
! declare a character array of type c_char and sufficient length:
character(c_char), dimension(200), target :: d1
integer :: ld1 ! will contain the string length
integer :: i
! the C pointer of character array d1 is passed:
call getstrfromc(ld1, c_loc(d1))
! read the first ld1 elements of array d1 as a character string, which will be returned:
stringa= transfer(d1(1:ld1), stringa)
write (6,*) 'SF d1: ', (d1(i),i=1,ld1)
write (6,*) 'SF stringa: "', trim(stringa),'"'
write (6,*) ''
return
end subroutine
module sfc
use iso_c_binding
implicit none
interface
subroutine getstrfromc(ld,d) bind(c,name='getString')
import :: c_int, c_ptr
integer(c_int) :: ld
type(c_ptr), value :: d
end subroutine getstrfromc
end interface
contains
subroutine strfromc(d1)
use iso_c_binding
implicit none
! declare a character array of type c_char and sufficient length:
character(c_char), dimension(200), target :: d1
integer :: ld1 ! will contain the string length
integer :: i
! the C pointer of character array d1 is passed:
call getstrfromc(ld1, c_loc(d1))
! clean elements after the ld1-th:
d1(ld1+1:)= ''
write (6,*) 'SF d1: ', (d1(i),i=1,ld1)
write (6,*) ''
return
end subroutine
end module sfc
C函数保持不变
。。。其他建议 为什么不简单地使用
C_CHAR
kind?我将您的代码“压缩”了一点:
program main
use, intrinsic :: iso_c_binding, only: C_INT, C_CHAR
implicit none
integer :: lw ! will contain the string length
character(256) :: w = "" ! will contain the string; Initialize to empty
! C interface
interface
subroutine getstrfromc( lw, w ) bind( c, name='getString' )
import :: C_INT, C_CHAR
implicit none
integer(C_INT), intent(out) :: lw
character(C_CHAR), intent(out) :: w(*)
end subroutine getstrfromc
end interface
! In Fortran variables are passed by default as "pointers".
call getstrfromc( lw, w )
! Write string
write (*,*) "Fortran: w: ", trim(w)
write (*,*) "Fortran: lw:", lw
end program main
C函数保持不变。你知道
字符(len=200)a
实际参数可以是与字符(len=1)b(*)相关联的参数吗?
(或b(200)
)伪参数?@francescalus我需要d1作为“目标”。我试着用它作为伪参数,编译器说我需要一个显式接口,用于子程序strfromcys,如果你有一个带有目标伪参数的strfromc
,你需要这个子程序有一个主程序的显式接口。如果你给它一个(比如说,把strflomc放到一个使用的模块中),那么它能工作吗?是的,它能工作,谢谢!我在“回答”中发布我的新代码。是的!非常感谢。现在我将研究并找出为什么我早期使用c_char的尝试没有成功。。。再次感谢你!