You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过iso_c_binding从Fortran调用C函数直接获取字符串?

Is there a more direct way to retrieve a C string in Fortran via iso_c_binding?

Yes, there are cleaner, more straightforward approaches to get a C string into Fortran using iso_c_binding—you don’t strictly need the transfer function, or you can simplify how you use it. Let’s walk through two improved methods based on your existing code:


1. Simplify buffer-based transfer (your original workflow)

Since your C function writes a null-terminated string to a buffer provided by Fortran, you can either:

  • Use the length value returned by C directly to slice the c_char array (no extra steps needed beyond what you’re already doing, but we can make it clearer)
  • Locate the null terminator (c_null_char) in the array for safer conversion (in case the returned length ever has issues)

Here’s a revised Fortran subroutine that cleans up the conversion step:

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

character(c_char), dimension(200), target :: d1
integer(c_int) :: ld1
integer :: null_pos

call getstrfromc(ld1, c_loc(d1))

! Option 1: Use the length returned by C (simple, matches your original logic)
stringa = transfer(d1(1:ld1), stringa)

! Option 2: Use the null terminator for safer conversion (fallback if length is wrong)
! null_pos = index(d1, c_null_char)
! if (null_pos > 0) then
!   stringa = transfer(d1(1:null_pos-1), stringa)
! else
!   stringa = transfer(d1, stringa)
! end if

write (6,*) 'SF stringa: "', trim(stringa),'"'
return
end subroutine

This removes unnecessary loops and keeps the conversion logic concise. The transfer function is still valid here, but we’re using it more intentionally instead of iterating through the array.


2. Let C return a string pointer (alternative workflow)

If you’re open to adjusting your C function, you can have it return a string pointer, then use Fortran’s c_f_pointer to map that pointer to a Fortran character array. This avoids preallocating a buffer in Fortran (though you still need to handle memory carefully).

Modified C function:

#include <stdio.h>
#include <string.h>

// Use a static buffer (no dynamic allocation, so no need to free in Fortran)
char* getString() {
    static char buf[200];
    printf("Enter a string:\n");
    scanf("%[^\n]", buf);
    printf("C: w: %s\n", buf);
    return buf;
}

Corresponding Fortran code:

program pr
implicit none
character(200) :: stringa
call strfromc(stringa)
write (6,*) 'FPR stringa: "', trim(stringa),'"'
stop
end program pr

subroutine strfromc(stringa)
use iso_c_binding
implicit none
character(200) :: stringa
interface
function getString() bind(c,name='getString')
import :: c_ptr
type(c_ptr) :: getString
end function getString
end interface

type(c_ptr) :: c_str_ptr
character(c_char), dimension(:), pointer :: f_char_arr
integer :: null_pos

! Get the C string pointer and map it to a Fortran array
c_str_ptr = getString()
call c_f_pointer(c_str_ptr, f_char_arr, [200]) ! Max buffer size matches C's static buf

! Convert to Fortran string using the null terminator
null_pos = index(f_char_arr, c_null_char)
if (null_pos > 0) then
  stringa = transfer(f_char_arr(1:null_pos-1), stringa)
else
  stringa = transfer(f_char_arr, stringa)
end if

write (6,*) 'SF stringa: "', trim(stringa),'"'
return
end subroutine

Note: If your C function uses dynamic allocation (malloc), you’ll need to add a corresponding C free function that Fortran can call via iso_c_binding to avoid memory leaks.


Key Takeaways

  • For your original buffer-passing approach, simplifying the slice-and-transfer step is the most direct improvement.
  • If you switch to a pointer-returning C function, c_f_pointer lets you map the C string directly to a Fortran array without manual buffer management (as long as you handle memory correctly).

内容的提问来源于stack exchange,提问作者Francesco Uboldi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:01:10