Fortran Coder
标题: 初次使用iso_c_binding实现c调用fortran出现问题,麻烦懂得指教 [打印本页]
作者: lcy_ouc 时间: 2017-10-20 21:42
标题: 初次使用iso_c_binding实现c调用fortran出现问题,麻烦懂得指教
程序如下:
[Fortran] 纯文本查看 复制代码
subroutine ricker(fz,tmax,dt,rick) Bind(C,Name="ricker")
use,intrinsic :: iso_c_binding
implicit none
integer(c_int) i,fz,tmax
real(c_float) dt,t,rick(0:tmax)
real,parameter :: PAI=3.141593
open(10,file='ricker.dat')
do i=0,tmax
t=i*dt
!rick(i)=(1-2*(PAI*fz*(t-1.2/fz))**2)*exp(-(PAI*fz*(t-1.2/fz))**2)
rick(i)=0.0
write(10,*) t,rick(i)
end do
close(10)
end subroutine ricker
[C] 纯文本查看 复制代码
#include <stdio.h>
void ricker(int fz,int tmax,float dt,float rick[]);
int main()
{
int fz,tmax;
float dt,t,rick[tmax+1];
fz=40;
tmax=500;
dt=0.001;
ricker(fz,tmax,dt,rick);
printf("ricker wavelet is computed!");
getchar();
return 0;
}
作者: kyra 时间: 2017-10-21 08:31
见如下注释
[Fortran] 纯文本查看 复制代码
subroutine ricker(fz,tmax,dt,prick) Bind(C,Name="ricker")
use,intrinsic :: iso_c_binding
implicit none
integer(c_int) , value :: fz,tmax !//传值
integer(c_int) :: i
real(c_float) , value :: dt!//传值
type(C_PTR) , value :: prick !//C指针
real(C_FLOAT) , pointer :: rick(:) !//fortran指针
real(C_FLOAT) :: t
real,parameter :: PAI=3.141593
call c_f_pointer( prick , rick , [tmax+1]) !//转换
rick(0:) => rick(1:)
open(10,file='ricker.dat')
do i=0,tmax
t=i*dt
!rick(i)=(1-2*(PAI*fz*(t-1.2/fz))**2)*exp(-(PAI*fz*(t-1.2/fz))**2)
rick(i)=0.0
write(10,*) t,rick(i)
end do
close(10)
end subroutine ricker
[C] 纯文本查看 复制代码
#include <stdio.h>
void ricker(int fz,int tmax,float dt,float rick[]);
int main(){
const int tmax=500;// tmax 必须为const,否则需要malloc为rick分配空间
int fz;
float dt,t,rick[tmax+1];
fz=40;
dt=0.001;
ricker(fz,tmax,dt,rick);
printf("ricker wavelet is computed!");
getchar();
return 0;
}
作者: lcy_ouc 时间: 2017-10-21 10:44
非常感谢你的回答,解决了很大问题!如果fortran程序中不调用库函数就没有问题。
当调用库函数时,比如这里调用了exp,就出现下述错误:
sub.o: In function `ricker':
sub.f90:(.text+0x292): undefined reference to `expf'
collect2: error: ld returned 1 exit status。
请问这个问题应如何解决?
作者: kyra 时间: 2017-10-21 11:43
exp 写成了 expf
作者: lcy_ouc 时间: 2017-10-21 12:06
这个没写错,就是错误提示expt了,很奇怪。
[Fortran] 纯文本查看 复制代码
subroutine ricker(fz,tmax,dt,prick) Bind(C,Name="ricker")
use,intrinsic :: iso_c_binding
implicit none
integer(c_int) ,value :: fz,tmax
integer(c_int) :: i
real(c_float) ,value :: dt
type(c_PTR) ,value :: prick
real(c_float) ,pointer :: rick(:)
real(c_float) :: t
real,parameter :: PAI=3.1415926
call c_f_pointer(prick,rick,[tmax+1])
rick(0:)=>rick(1:)
!integer(c_int) i,fz,tmax
!real(c_float) dt,t,rick(0:tmax)
!real,parameter :: PAI=3.141593
!open(10,file='ricker.dat')
do i=0,tmax
t=i*dt
rick(i)=(1-2*(PAI*fz*(t-1.2/fz))**2)*exp(-(PAI*fz*(t-1.2/fz))**2)
!rick(i)=0.0
! write(10,*) t,rick(i)
end do
!close(10)
end subroutine ricker
作者: kyra 时间: 2017-10-21 13:31
我这里一切正常,可以运行,并且得到结果
0.00000000 -1.84434939E-05
1.00000005E-03 -4.36428018E-05
2.00000009E-03 -9.97947573E-05
3.00000003E-03 -2.20462069E-04
4.00000019E-03 -4.70417872E-04
5.00000035E-03 -9.69250163E-04
6.00000005E-03 -1.92774425E-03
7.00000022E-03 -3.69966868E-03
8.00000038E-03 -6.84840605E-03
9.00000054E-03 -1.22209908E-02
1.00000007E-02 -2.10113153E-02
1.10000009E-02 -3.47787663E-02
1.20000001E-02 -5.53741939E-02
1.30000003E-02 -8.47148746E-02
1.40000004E-02 -0.124358617
1.50000006E-02 -0.174860358
1.60000008E-02 -0.234961614
1.70000009E-02 -0.300758570
1.80000011E-02 -0.365095139
1.90000013E-02 -0.417494863
2.00000014E-02 -0.444934517
2.10000016E-02 -0.433627903
2.20000017E-02 -0.371734262
2.30000019E-02 -0.252568901
2.40000002E-02 -7.75822029E-02
2.50000004E-02 0.141793832
2.60000005E-02 0.384229809
2.70000007E-02 0.620928466
2.80000009E-02 0.820190012
2.90000010E-02 0.953244746
3.00000012E-02 1.00000000
3.10000014E-02 0.953244746
3.20000015E-02 0.820190012
3.29999998E-02 0.620928884
3.40000018E-02 0.384229809
3.50000001E-02 0.141794279
3.60000022E-02 -7.75822029E-02
3.70000005E-02 -0.252568901
3.80000025E-02 -0.371734470
3.90000008E-02 -0.433627903
4.00000028E-02 -0.444934517
4.10000011E-02 -0.417494863
4.20000032E-02 -0.365095019
4.30000015E-02 -0.300758570
4.40000035E-02 -0.234961465
4.50000018E-02 -0.174860358
4.60000038E-02 -0.124358535
4.70000021E-02 -8.47148746E-02
4.80000004E-02 -5.53742386E-02
4.90000024E-02 -3.47787663E-02
5.00000007E-02 -2.10113153E-02
5.10000028E-02 -1.22209908E-02
5.20000011E-02 -6.84840605E-03
5.30000031E-02 -3.69966868E-03
5.40000014E-02 -1.92774425E-03
... ...
0.453000009 -0.00000000
0.454000026 -0.00000000
0.455000013 -0.00000000
0.456000030 -0.00000000
0.457000017 -0.00000000
0.458000034 -0.00000000
0.459000021 -0.00000000
0.460000008 -0.00000000
0.461000025 -0.00000000
0.462000012 -0.00000000
0.463000029 -0.00000000
0.464000016 -0.00000000
0.465000033 -0.00000000
0.466000021 -0.00000000
0.467000008 -0.00000000
0.468000025 -0.00000000
0.469000012 -0.00000000
0.470000029 -0.00000000
0.471000016 -0.00000000
0.472000033 -0.00000000
0.473000020 -0.00000000
0.474000037 -0.00000000
0.475000024 -0.00000000
0.476000011 -0.00000000
0.477000028 -0.00000000
0.478000015 -0.00000000
0.479000032 -0.00000000
0.480000019 -0.00000000
0.481000036 -0.00000000
0.482000023 -0.00000000
0.483000010 -0.00000000
0.484000027 -0.00000000
0.485000014 -0.00000000
0.486000031 -0.00000000
0.487000018 -0.00000000
0.488000035 -0.00000000
0.489000022 -0.00000000
0.490000010 -0.00000000
0.491000026 -0.00000000
0.492000014 -0.00000000
0.493000031 -0.00000000
0.494000018 -0.00000000
0.495000035 -0.00000000
0.496000022 -0.00000000
0.497000009 -0.00000000
0.498000026 -0.00000000
0.499000013 -0.00000000
0.500000000 -0.00000000
作者: lcy_ouc 时间: 2017-10-21 14:11
我是用这三个命令编译的:
gfortran -c sub.f90;
gcc -c main.c;
gcc -o main.exe main.o sub.o。
gfortran与gcc版本是4.8.4。是否存在问题?
作者: kyra 时间: 2017-10-21 17:18
没问题。我觉得你应该仔细的检查代码。是否自己编辑的,编译的,不是同一个。
作者: lcy_ouc 时间: 2017-10-22 08:53
好的,再次感谢kyra!
作者: lcy_ouc 时间: 2017-10-23 20:29
kyra,你好,今天偶然看到了我之前的问题在哪里。在最后一步连接为exe文件时,应该用gfortran,而不是gcc。
作者: kyra 时间: 2017-10-23 21:16
哦,对。
其实用 gcc 也可以。加上
gcc -o main.exe main.o sub.o -lgfortran
本质上是一样的,实际上连接器都是 ld
作者: lcy_ouc 时间: 2017-10-23 21:25
学习了,谢谢!
欢迎光临 Fortran Coder (http://bbs.fcode.cn/) |
Powered by Discuz! X3.2 |