我們有運行在一組數據陣列的並想程度的代碼,以便我們可以有幾套的數據的傳統的Fortran 90的代碼。不幸的是,子程序都沒有輸入參數,而是通過模塊評估所有數據。以下代碼類似於我們的Fortran代碼。使用C指針跟蹤的Fortran模塊數據成員
MODULE test_mod
IMPLICIT NONE
double precision, pointer :: f_x(:)
integer :: n = 5
END MODULE test_mod
SUBROUTINE alloc_x()
use test_mod
IMPLICIT NONE
allocate(f_x(n))
END SUBROUTINE alloc_x
SUBROUTINE init_x()
USE test_mod
IMPLICIT NONE
f_x = 1.0
END SUBROUTINE init_x
SUBROUTINE dealloc_x()
use test_mod
IMPLICIT NONE
deallocate(f_x)
END SUBROUTINE dealloc_x
由於Fortran代碼就夠了複雜(有大約一百陣列且全部在不同形狀和尺寸),則較少的代碼更好的修改。我們提出了以下解決方案,並對此解決方案是否與Fortran 90標準兼容感興趣:
我們創建了兩個額外的Fortran子例程,用於存儲分配的Fortran陣列的位置並將c指針複製回模塊。
#include <stdio.h>
#include <stdlib.h>
void alloc_x_();
void init_x_();
void dealloc_x_();
void store_ptrs_(double **c_x);
void copy_ptrs2mod_(double **c_x);
void output_result(int entry, double* array);
int main()
{
int i;
double *x[10];
/* allocate array */
for(i=0; i<10; i++){
alloc_x_();
store_ptrs_(&x[i]);
}
/* initialize array */
for(i=0; i<10; i++){
copy_ptrs2mod_(&x[i]);
init_x_();
output_result(i,x[i]);
}
/* deallocate the array */
for(i=0; i<10; i++){
copy_ptrs2mod_(&x[i]);
dealloc_x_();
}
}
void output_result(int entry, double* array){
int j;
printf("x[%2d] = [", entry);
for (j = 0; j < 5; ++j)
{
if (j == 4)
{
printf("%3.1f",array[j]);
continue;
}
printf("%3.1f, ",array[j]);
}
printf("]\n");
}
輸出 - -
SUBROUTINE store_ptrs(c_x)
use iso_c_binding
use test_mod
IMPLICIT NONE
TYPE(c_ptr) :: c_x
c_x = c_loc(f_x)
END SUBROUTINE
SUBROUTINE copy_ptrs2mod(c_x)
use iso_c_binding
use test_mod
IMPLICIT NONE
TYPE(c_ptr) :: c_x
CALL c_f_pointer(c_x,f_x,[n])
END SUBROUTINE
有了這兩個子程序,我們可以無需修改Fortran代碼有更多的數據是一個副本(在下面的代碼10份)
x[ 0] = [1.0, 1.0, 1.0, 1.0, 1.0]
x[ 1] = [1.0, 1.0, 1.0, 1.0, 1.0]
x[ 2] = [1.0, 1.0, 1.0, 1.0, 1.0]
x[ 3] = [1.0, 1.0, 1.0, 1.0, 1.0]
x[ 4] = [1.0, 1.0, 1.0, 1.0, 1.0]
x[ 5] = [1.0, 1.0, 1.0, 1.0, 1.0]
x[ 6] = [1.0, 1.0, 1.0, 1.0, 1.0]
x[ 7] = [1.0, 1.0, 1.0, 1.0, 1.0]
x[ 8] = [1.0, 1.0, 1.0, 1.0, 1.0]
x[ 9] = [1.0, 1.0, 1.0, 1.0, 1.0]
雖然我們還沒有看到任何這方面的問題,我們都有點擔心,我們可能會(隱含的)依靠編譯器的各種標準的具體實施中,或者一些其他incompa使用更新的標準可能會妨礙這項工作。我們將非常感謝您對此方法的任何意見或反饋,以處理舊版Fortran 90代碼中常見的問題。
iso_c_binding'不規範直到2003年的Fortran – francescalus
的Fortran 90是完全過時模塊'。忘記它,不需要符合Fortran 90。使用*至少* Fortran 95固定最大的問題,但更好的Fortran 2003或2008。 –