如何在Fortran中访问作为C函数指针传递的2d数组。下面是我的代码
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
下面是我的C代码
#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");
}
}
}
下面是输出
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: ========
我无法在Fortran中打印修改后的值。谁能提出工资产出的可能原因是什么?
首先,你的代码不是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