新版Intel Fortran Compiler下获取多态对象C指针的修复咨询
修复ifort 2021.6.0下
c_loc作用于多态对象的编译错误 问题原因
Fortran标准明确规定c_loc的参数不能是多态对象(包括class(*)类型的实体),旧版Intel Fortran编译器(ifort)放宽了该限制,允许对多态对象调用c_loc,但2021.6.0版本开始严格遵循标准,因此触发#9023错误。
解决方案
方案1:标准合规的select type匹配(推荐)
由于你实际仅使用少数简单结构体和标量类型,可以通过select type逐个匹配这些类型,对每个非多态的具体类型调用c_loc,完全符合Fortran标准,且兼容性最好:
!> Send an arbitrary scalar object. function SendObject(my, obj) result(ok) use, intrinsic :: iso_c_binding implicit none class(Socket) :: my class(*), target, intent(in) :: obj type(c_ptr) :: ptr integer(c_size_t) :: len logical :: ok ok = .false. select type (obj) ! 匹配你实际用到的标量类型 type is (integer) ptr = c_loc(obj) len = c_sizeof(obj) ok = my%SendData(ptr, len) type is (real) ptr = c_loc(obj) len = c_sizeof(obj) ok = my%SendData(ptr, len) type is (double precision) ptr = c_loc(obj) len = c_sizeof(obj) ok = my%SendData(ptr, len) ! 匹配你自定义的结构体类型 type is (MySimpleStruct) ptr = c_loc(obj) len = c_sizeof(obj) ok = my%SendData(ptr, len) ! 可以继续添加其他你用到的类型 class default ! 处理未匹配的类型,比如输出错误信息 write(*,*) "Unsupported object type in SendObject" end select end function
方案2:非标准的编译器扩展(快速适配)
如果你不想逐个匹配类型,可以利用ifort支持的非标准loc函数,通过transfer将对象地址转换为c_ptr类型,模拟旧版编译器的行为:
!> Send an arbitrary scalar object. function SendObject(my, obj) result(ok) use, intrinsic :: iso_c_binding implicit none class(Socket) :: my class(*), target, intent(in) :: obj type(c_ptr) :: ptr integer(c_size_t) :: len logical :: ok ! 利用loc获取对象地址,transfer转换为c_ptr类型 ptr = transfer(loc(obj), c_ptr) len = c_sizeof(obj) ok = my%SendData(ptr, len) end function
注意:该方法依赖Intel Fortran的loc扩展,不保证在其他Fortran编译器(如GCC的gfortran)下能正常工作,仅作为快速适配旧代码的临时方案。
内容的提问来源于stack exchange,提问作者ridiculous_fish
相关产品推荐
相关产品推荐

