在 Fortran 中,可以使用 C_LOC
和 C_F_POINTER
結合的方法來實現不同類型指針指向同一塊內存區域。以下是具體方法和示例:
關鍵步驟:
- 獲取內存地址:用
C_LOC
獲取原始數組的 C 地址。 - 類型轉換:用
C_F_POINTER
將地址轉換為目標類型的 Fortran 指針。
示例代碼
program type_punning_exampleuse, intrinsic :: iso_c_bindingimplicit none! 定義原始數組(例如整數類型)integer, target :: int_array(4)integer :: i! 定義目標類型的指針(例如實數類型)real, pointer :: real_ptr(:)! 初始化原始數組do i = 1, 4int_array(i) = iend do! 將整數數組的地址轉換為實數指針call c_f_pointer(c_loc(int_array), real_ptr, [4])! 驗證結果print *, "Original integers: ", int_arrayprint *, "Mapped as reals: ", real_ptrend program type_punning_example
注意事項:
- 內存對齊:確保兩種類型的內存布局兼容(例如
integer
和real
可能占用相同字節數,但需確認具體編譯器實現)。 - 字節順序:跨類型訪問時需注意大端/小端問題(尤其在異構平臺間)。
- 標準符合性:此方法符合 Fortran 2003 及以后的標準(依賴
iso_c_binding
)。 - 邊界安全:確保目標指針的尺寸不超過原始緩沖區范圍。
更通用的緩沖區映射
若需處理任意字節緩沖區,可結合 character
類型和 transfer
函數:
program raw_buffer_exampleuse, intrinsic :: iso_c_bindingimplicit nonecharacter(len=16), target :: buffer ! 16字節的原始緩沖區real, pointer :: float_view(:)integer, pointer :: int_view(:)! 將緩沖區映射為實數數組call c_f_pointer(c_loc(buffer), float_view, [4]) ! 假設 real 占4字節! 同一緩沖區映射為整數數組call c_f_pointer(c_loc(buffer), int_view, [4]) ! 假設 integer 占4字節! 操作其中一個視圖會影響另一個float_view = [1.0, 2.0, 3.0, 4.0]print *, "As integers: ", int_viewend program raw_buffer_example
限制:
- Fortran 不允許直接對指針進行算術運算(需借助數組切片或臨時變量)。
- 非連續數組(如帶
stride
的)需要更復雜的描述符處理。
如需進一步控制內存布局,可考慮與 C 語言的互操作(通過 bind(c)
接口)。