混合编程
- 1、C调Fortran:判断两个数的最大值,C输入,Fortran判断
- 2、Fortran调C:二维数组运算,Fortran进行相关定义,C运算
- 3、遇到的问题
1、C调Fortran:判断两个数的最大值,C输入,Fortran判断
fortran.f90
subroutine maxnum(x,y)integer :: x,yif(x > y) thenprint *, xelseprint *, yend if
end subroutine maxnum
c.c
#include<stdio.h>
void maxnum_(int*, int*);
int main(){int a,b;printf("请输入要比较的两个数\n");scanf("%d%d",&a,&b);maxnum_(&a, &b);
}
test: fortran.f90 c.cgcc -c c.c -o c.ogfortran -c fortran.f90 -o fortran.ogfortran -o test fortran.o c.o#gcc -o test c.o fortran.o
2、Fortran调C:二维数组运算,Fortran进行相关定义,C运算
fortranCallC.f90
program callCimplicit noneexternal :: sum_c !调用C的函数 integer(kind=8),dimension(3,3) :: arrinteger :: i,ji=0j=0print *,'输入3x3的矩阵,回车隔开:'!一个二维矩阵do i = 1, 3do j =1, 3read *, arr(i,j)end do end do !调用c函数进行计算! do i = 1, 3! do j =1, 3! print *,arr(i,j)! end do!end docall sum_c(arr)
end program callc
CCallFortran.c
#include<stdio.h>void sum_c_(int arr[][3]){int sum = 0;//printf("sizeof(arr) is %ld\n",sizeof(*arr)); 查看数组所占内存,输出是12,但我输出15个数才得到全部的arr的值//相关文档没有发现,但是多次运行发现传过来的二维数组索引需要+2for(int i=0; i<=4; i+=2){for(int j=0 ;j<=4; j+=2){// printf("222222");用来检验非编译错误,上面把j++写成i++sum += *(arr[j]+i);printf("传过来的数组值:%d\n",arr[j][i]);}}printf("the sum is %d\n",sum);
}
makefile
test: CCallFortran.c fortranCallC.f90gfortran -c fortranCallC.f90 -o fortranCallC.ogcc -c CCallFortran.c -o CCallFortran.ogfortran -o test CCallFortran.o fortranCallC.o
3、遇到的问题
1、逗号写成中文状态,使用vim编辑不利于排错,也是我对这件事的反映不够,加强表征印象
2、Fortran调用c语言,二维数组运算
参考1
参考2
相互调用参考
3、C语言中 指针做函数参数传递二维数组 ,Fortran调用c的函数,需要指针作为参数,所以有了下面这些问题:
关于参数是二维数组指针的操作
我疑惑传入参数后,为什么不用*来表示变量值 参考
#include <stdio.h>
void fun(int (*p1)[3],int (*p2)[3]);
int main()
{
int p1[3][3]={{7,8,9},{4,5,6},{1,2,3}} ;
int p2[3][3] = {0};
int i = 0, j = 0;
fun(p1,p2);
for(i = 0;i < 3;i++){
for(j = 0;j < 3;j++){
printf("%d ",*(*(p2+i)+j));
}
printf("\n");
}
return 0;
}
void fun(int (*p1)[3],int (*p2)[3])
{
int i = 0,j = 0;
for(i = 0;i < 3;i++){
for(j = 0;j < 3;j++){
*(p2[j]+i) = *(p1[i]+j);
}
}
}
https://blog.csdn.net/hsajas/article/details/83586774
一个c语言程序中没有或一个main函数
f.f90:(.text+0x11): multiple definition of `main’
不知对错的一种写法
program mainendsubroutine maxnum(x,y) bind(c)
use,intrinsic :: iso_c_bindinginteger(kind=4) :: x,yread(*,*) x, yif(x > y) thenprint *, xelseprint *, yend if
end subroutine maxnum
记录一下,以上
4、在链接时c和frotran时出现的问题
fortran.f90:(.text+0x66): undefined reference to _gfortran_st_write' fortran.f90:(.text+0x84): undefined reference to
_gfortran_transfer_integer_write’
fortran.f90:(.text+0x93): undefined reference to _gfortran_st_write_done' fortran.f90:(.text+0xd0): undefined reference to
_gfortran_st_write’
fortran.f90:(.text+0xee): undefined reference to _gfortran_transfer_integer_write' fortran.f90:(.text+0xfd): undefined reference to
_gfortran_st_write_done
以上使用gcc编译时出现的问题,可能是我将两个文件(c和fortran的编译文件链接时使用gcc方的顺序不对)
gcc -c c.c -o c.o
gfortran -c fortran.f90 -o fortran.o
#gfortran -o test fortran.o c.o
gcc -o test c.o fortran.o
fortran.o: In function maxnum_': fortran.f90:(.text+0x66): undefined reference to
_gfortran_st_write’
fortran.f90:(.text+0x84): undefined reference to _gfortran_transfer_integer_write' fortran.f90:(.text+0x93): undefined reference to
_gfortran_st_write_done’
fortran.f90:(.text+0xd0): undefined reference to _gfortran_st_write' fortran.f90:(.text+0xee): undefined reference to
_gfortran_transfer_integer_write’
fortran.f90:(.text+0xfd): undefined reference to `_gfortran_st_write_done’
collect2: error: ld returned 1 exit status
makefile:2: recipe for target ‘test’ failed
make: *** [test] Error 1
使用gcc先编译c的也不行
就是要用gfortran吗?总之fortran是可以的
5、Makefile的使用记得一定要tab
混编程的最后链接最好使用gfortran别用gcc(鄙见),不然会出现一堆难以理解的错误参考
6、在fortran调用c的时候出现的错误
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
无效的内存引用
感谢
@Alex_the_Dawn
@0_382
@詹坤林
无私分享