我想将Fortran(real*8
,比如说)数组解释为一个字节数组,以便可以将它发送到函数来处理字节级别的事物。什么是一种简单(最好是无副本)的方法来实现这个目标?
答案 0 :(得分:1)
首先,不清楚在字节级上工作的函数是什么。它使用Fortran字符吗?还是1字节整数?他们是Fortran的不同野兽。
您可以尝试对函数的签名撒谎,并按原样传递数组。可能工作,而不是严格的标准符合。
Transfer()
是用于类似目的的最佳现代工具,但它确实可能涉及临时工具。
如果数组的大小是固定的(它不是可分配的或指针或伪参数),你可以使用equivalence
,这与C中的union
非常相似。
但是你必须小心允许什么,这是一个臭名昭着的狡猾领域。即使C联合规则也不同于C ++规则。 Fortran等价有自己的规则,更严格,我担心。不允许使用类型惩罚,但是野外的许多代码都是这样做的。
用C指针做技巧并从不同类型的不同指针指向相同的数组肯定不符合标准,在某些情况下可能会给你预期的结果而在其他情况下会给你错误的结果(在C和C ++中它们称之为未定义的行为) )。
答案 1 :(得分:1)
“NO_COPY”方式......但依赖于DEC扩展:
USE ISO_C_BINDING
IMPLICIT NONE
UNION
MAP
REAL(KIND=C_DOUBLE) , DIMENSION(N) :: R8_Data
END MAP
MAP
BTYE , DIMENSION(N*8) :: B_Data
END MAP
MAP
CHARACTER(LEN=1) , DIMENSION(N*8) :: C_Data
END MAP
MAP
INTEGER(KIND=C_Int16_T), DIMENSION(N*4) :: I2_Data
END MAP
MAP
INTEGER(KIND=C_Int32_T), DIMENSION(N*2) :: I4_Data
END MAP
END UNION
@Valdimir等效也可以在没有访问DEC扩展的情况下工作。
有一个升级到gfortran以添加MAP和UNION DEC扩展,所以它也会及时出现。
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56226
我对这种差异的欣赏又回到了正轨...... 可以在结构内部使用UNION / MAP。在结构/ TYPE之外,那么所有人都需要EQUIVALENCE。
因此弗拉基米尔提到这也是“没有副本”......
REAL(KIND=C_DOUBLE) , DIMENSION(N) :: R8_Data
BTYE , DIMENSION(N*8) :: B_Data
CHARACTER(LEN=1) , DIMENSION(N*8) :: C_Data
INTEGER(KIND=C_Int16_T), DIMENSION(N*4) :: I2_Data
INTEGER(KIND=C_Int32_T), DIMENSION(N*2) :: I4_Data
EQUIVALENCE(R8_Data, I4_Data)
除非有特定的问题,否则它几乎比它的价值更危险。