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

无需C粘合代码将Fortran字符串传入Go生成的C共享库问题求解

问题原因与解决方案

代码存在4个核心错误导致参数传递异常,Go侧拿到的字符串长度是栈上垃圾值,才会触发超大内存分配报错:

  1. 结构体参数传递方式错误:C头文件中MyFunc的参数是GoString值传递,而Fortran默认参数传递为引用传递,导致Go侧拿到的结构体内容完全错误。
  2. 接口定义不匹配:接口块中绑定的函数名是MyFunc,但结束语句错误写为end function Validate,导致函数绑定失效,调用逻辑完全错乱。
  3. 返回值类型错误:Go导出函数返回值是GoUint8(对应C的unsigned char),错误声明为integer(c_ptrdiff_t)会破坏栈结构,进一步导致参数传递异常。
  4. 不必要的C_NULL_CHAR后缀:Go字符串不需要以NULL结尾,追加空字符反而可能导致字符串内容不符合预期。

修正后的完整代码

module go_types
    use iso_c_binding
    implicit none
    ! 和C头文件的GoString结构体内存布局完全对齐
    type, bind(c) :: go_string
        type(c_ptr) :: p
        integer(c_ptrdiff_t) :: n
    end type go_string
end module go_types

program test_go
    use, intrinsic :: iso_c_binding
    use go_types
    implicit none

    ! 修正接口定义:返回值类型正确,参数加value属性声明为值传递
    interface        
        function MyFunc(str1, str2) bind(C, name="MyFunc")
            use iso_c_binding
            use go_types            
            integer(c_uint8_t) :: MyFunc
            type(go_string), intent(in), value :: str1
            type(go_string), intent(in), value :: str2
        end function MyFunc
    end interface

    type(go_string) :: str1, str2
    character(len=25), target :: fortstr1, fortstr2
    integer(c_uint8_t) :: ret

    ! 不需要追加C_NULL_CHAR,Go字符串不依赖空结束符
    fortstr1 = "Bar"
    str1%p = c_loc(fortstr1)
    ! 直接取trim后的实际有效长度
    str1%n = len_trim(fortstr1)

    fortstr2 = "Foo"
    str2%p = c_loc(fortstr2)
    str2%n = len_trim(fortstr2)

    ret = MyFunc(str1, str2)
    print *, 'return code:', ret

end program test_go

补充说明

如果你的Fortran编译器要求显式设置字符串为C字符类型,可以将字符串声明改为character(kind=c_char, len=25), target :: fortstr1, fortstr2,绝大多数情况下默认的字符类型和c_char是兼容的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 06:24:03