2016-09-30 15 views
-1

C関数からポインタとして渡されるFortranの2次元配列にどのようにしてアクセスできますか?以下は、以下の私のCコードの下FortranのポインタとしてCから渡された2次元配列

#include <stdio.h> 
    void print2(double *p, int n) 
    { 
    printf("Array from C is \n"); 
    double *dptr; 
    int i,j; 
    dptr = (double *)p; 
    for (i = 0; i < n; i++) 
    { 
    for (j = 0; j<n; j++) 
     { 
     printf("%.6g \t",dptr[i*n+j]); 

     *(p+i*n+j)=1; 
     printf("\n"); 
    } 
    } 
} 

は、私がFortranで変更された値を印刷することはできませんよ出力

Array from C is 
1  4  7 
1  5  8 
1  6  9 
xyz(i,j)   1   1 1.00000000000000 
xyz(i,j)   2   1 1.00000000000000 
xyz(i,j)   3   1 1.00000000000000 
xyz(i,j)   1   2 4.00000000000000 
xyz(i,j)   2   2 5.00000000000000 
xyz(i,j)   3   2 6.00000000000000 
xyz(i,j)   1   3 7.00000000000000 
xyz(i,j)   2   3 8.00000000000000 
xyz(i,j)   3   3 9.00000000000000 
*** glibc detected *** ./main.exe: free(): invalid next size (normal): 0x000000000093c290 *** 
======= Backtrace: ========= 
/lib64/libc.so.6[0x320ea75f4e] 
/lib64/libc.so.6[0x320ea78cf0] 
./main.exe[0x408786] 
./main.exe[0x4240bc] 
./main.exe[0x429f54] 
./main.exe[0x402e63] 
/lib64/libc.so.6(__libc_start_main+0xfd)[0x320ea1ed5d] 
./main.exe[0x402d69] 
======= Memory map: ======== 

されている私のコード

program linkFwithC 
    use iso_c_binding 
    implicit none 
    interface 
     subroutine my_routine(p,r) bind(c,name='print2') 
     import :: c_ptr 
     import :: c_int 
     type(c_ptr), value :: p 
     integer(c_int), value :: r 
     end subroutine 
    end interface 
    REAL, POINTER :: PTR2 
    integer i,j 
    integer,parameter ::n=3 
    real (c_double), allocatable, target :: xyz(:,:) 
    real (c_double), target :: abc(3,3) 
    type(c_ptr) :: cptr 
    allocate(xyz(n,n)) 
    cptr = c_loc(xyz(1,1)) 

    !Inputing array valyes 

    xyz(1,1)= 1 
    xyz(1,2)= 2 
    xyz(1,3)= 3 
    xyz(2,1)= 4 
    xyz(2,2)= 5 
    xyz(2,3)= 6 
    xyz(3,1)= 7 
    xyz(3,2)= 8 
    xyz(3,3)= 9 


    call my_routine(cptr,n) 

    do j=1,n 
    do i=1,n 

    print*,"xyz(i,j)",i,j,xyz(j,i) 

    enddo 
    enddo 
    deallocate(xyz) 
! pause 
    end program linkFwithC 

です。誰でも賃金の出力が可能な理由を示唆することはできますか?

+0

:http://stackoverflow.com/questions/27584674/passing-2d-array-from-fortran -to-c、http://stackoverflow.com/questions/27582715/passing-a-two-dimentional-array-from-fortran-to-c –

+0

あなたは、Fortran内の2次元の割り付け可能な配列に次のような連続したメモリがあることを確信していますか?静的な2次元配列?結果は反対の結果を示すように見えるので。そして、多次元配列に関しては、C&FORTRANが転置されていることを忘れないでください。 –

+0

@ Jean-FrançoisFabreはい、彼らは常に、常にcontigousメモリです。 [tag:c]から* lapack * [tag:fortran]へのポインタを渡すサンプルプログラムについては、googleを利用できます。 –

答えて

0

まず、あなたのコードはFORTRANではなくFortranです。 C言語の相互運用性のための機能がかなり後になりました。あなたは既にこのような質問の多くを尋ね第二に、次のコード

#include <stdio.h> 
void print2(double *p, int n) 
{ 
    double *dptr; 
    int i,j; 

    /* Why are you making a copy here? 
    * Did you intent to pass by value or reference? 
    */ 
    dptr = p; 
    printf("Array from C is \n"); 
    for(i = 0; i < n; i++){ 
    for(j = 0; j < n; j++){ 
     printf("%.6g \t", dptr[i*n+j]); 
     *(p+i*n+j)=1; 
     printf("\n"); 
    } 
    } 
} 

module mymod 

    use ISO_C_binding, only: & 
     c_ptr, & 
     c_int 

    ! Explicit typing only 
    implicit none 

    interface 
    subroutine my_routine(p, r) bind(c, name='print2') 
     import :: c_ptr, c_int 
     type(c_ptr), value :: p 
     integer(c_int), value :: r 
    end subroutine my_routine 
    end interface 

end module mymod 

program main 

    use ISO_Fortran_env, only: & 
    compiler_version, & 
    compiler_options 

    use ISO_C_binding, only: & 
    c_double, & 
    c_ptr, & 
    c_loc 

    use mymod, only: & 
    my_routine 

    ! Explicit typing only 
    implicit none 

    integer i, j 
    integer, parameter :: N = 3 
    real(c_double), allocatable, target :: xyz(:,:) 
    type(c_ptr) :: cptr 

    ! Allocate memory 
    allocate(xyz(N, N)) 

    ! Get C-language address 
    cptr = c_loc(xyz(1,1)) 

    ! Inputting array values 
    xyz(1,1)= 1 
    xyz(1,2)= 2 
    xyz(1,3)= 3 
    xyz(2,1)= 4 
    xyz(2,2)= 5 
    xyz(2,3)= 6 
    xyz(3,1)= 7 
    xyz(3,2)= 8 
    xyz(3,3)= 9 

    call my_routine(cptr, N) 

    do j=1, N 
     do i=1, N 
     print *, "xyz(i,j)", i, j, xyz(j, i) 
     end do 
    end do 

    ! Release memory 
    deallocate(xyz) 

    print '(/4a/)', & 
    ' This file was compiled using ', compiler_version(), & 
    ' using the options ', compiler_options() 

end program main 

利回り

gfortran -Wall -o main.exe print2.c mymod.f90 main.f90 
./main.exe 

Array from C is 
1 
4 
7 
2 
5 
8 
3 
6 
9 
xyz(i,j)   1   1 1.0000000000000000  
xyz(i,j)   2   1 1.0000000000000000  
xyz(i,j)   3   1 1.0000000000000000  
xyz(i,j)   1   2 1.0000000000000000  
xyz(i,j)   2   2 1.0000000000000000  
xyz(i,j)   3   2 1.0000000000000000  
xyz(i,j)   1   3 1.0000000000000000  
xyz(i,j)   2   3 1.0000000000000000  
xyz(i,j)   3   3 1.0000000000000000  

This file was compiled using GCC version 6.1.1 20160802 using the options -mtune=generic -march=x86-64 -Wall 
+1

修正した内容を説明できますか? –

+0

変更を見ることができません – user1131484

+0

はいCコードのビット変化:used void * – user1131484

関連する問題