从C调用Fortran函数时EXC_访问错误
我环顾了一下四周,虽然有很多EXC_BAD_访问问题,但都没有起到作用 我使用的是山狮(我想是OSX10.8吧?)和PGI12 我似乎无法从C中调用fortran函数,我已经编写了一个简化的案例,似乎无法传递整数 我的fortran函数是:从C调用Fortran函数时EXC_访问错误,c,fortran,fortran-iso-c-binding,C,Fortran,Fortran Iso C Binding,我环顾了一下四周,虽然有很多EXC_BAD_访问问题,但都没有起到作用 我使用的是山狮(我想是OSX10.8吧?)和PGI12 我似乎无法从C中调用fortran函数,我已经编写了一个简化的案例,似乎无法传递整数 我的fortran函数是: 1 integer function smallFortran(a) result(res) bind(c,name='smallFortran_') 2 !integer function smallFortran(a) result(res)
1 integer function smallFortran(a) result(res) bind(c,name='smallFortran_')
2 !integer function smallFortran(a) result(res)
3
4 use ISO_C_BINDING
5 implicit none
6
7 integer(kind=c_int), intent(IN) :: a
8 !integer, intent(IN) :: a
9
10 print *,'A = ', a
11 res = a;
12
13 endfunction smallFortran
我的C函数是
int main() {
int ier=7;
ier = smallFortran_(8);
}
建造它
matt@pontus:diffFst$ make
pgcc -c cDoDiffFst.c
PGC-W-0267-#warning -- "Unsupported compiler detected" (/usr/include/sys/cdefs.h: 81)
PGC/x86-64 OSX 12.9-0: compilation completed with warnings
pgcc -g -O0 -traceback -o cDoDiffFst cDoDiffFst.o smallFortran.o -lpgf90 -lpghpf2 -lpgf90rtl -lpgftnrtl -lpghpf_rpm
(我希望警告不是导致我出现问题的原因,他们对此的回应是,他们将发送一个更新版本的文件,但我还没有得到回复。不知道为什么PGI需要指定这么多额外的库)
当我在调试器中运行它时
matt@pontus:diffFst$ gdb cDoDiffFst
(gdb) run
Starting program: /Users/matt/aurams/trunk/utils/diffFst/cDoDiffFst
Reading symbols for shared libraries +............................. done
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000008
0x0000000100001906 in _smallFortran_ (a=Cannot access memory at address 0x8
) at smallFortran.f90:10
10 print *,'A = ', a
(gdb)
我完全迷路了,为什么我不能发送int?我试着给一个整数赋值并发送它,没有骰子。我试过把它作为一个子程序,我试过了,没有返回值。。什么都不管用。这个错误应该清楚地表明出了什么问题
smallFortran_uquo;
希望它的参数通过引用传递(fortran中的所有参数都是这样——注意,我在这里有点快而且松散),并尝试访问指针8
处的数据,但失败了。修复很容易;函数需要一个指针,因此请为它指定一个:
int main() {
int ier = 7;
int arg = 8;
ier = smallFortran_(&arg);
}
这假设fortran
integer
类型对应于有问题的编译器的Cint
;您可能需要设置arg
along
,否则。该错误应能清楚地说明问题所在smallFortran_uquo;
希望它的参数通过引用传递(fortran中的所有参数都是这样——注意,我在这里有点快而且松散),并尝试访问指针8
处的数据,但失败了。修复很容易;函数需要一个指针,因此请为它指定一个:
int main() {
int ier = 7;
int arg = 8;
ier = smallFortran_(&arg);
}
这假设fortran
integer
类型对应于有问题的编译器的Cint
;您可能需要将arg
设为long
。这里有一个替代解决方案,说明如何编写Fortran以匹配问题的原始C。键是声明上的值
限定符。使用Fortran ISO C绑定,可以匹配C传递参数的各种方式。您还可以取消例程名称中的下划线。。。这就是bind
的name
关键字的用途
调用中不带下划线的C代码:
int main() {
int ier=7;
ier = smallFortran (8);
}
和匹配的Fortran:
function smallFortran(a) result(res) bind(c,name='smallFortran')
use ISO_C_BINDING
implicit none
integer(kind=c_int), intent(IN), value :: a
integer(kind=c_int) :: res
print *,'A = ', a
res = a;
endfunction smallFortran
这里有一个替代解决方案,展示了如何编写Fortran来匹配问题的原始C语言。键是声明上的
值
限定符。使用Fortran ISO C绑定,可以匹配C传递参数的各种方式。您还可以取消例程名称中的下划线。。。这就是bind
的name
关键字的用途
调用中不带下划线的C代码:
int main() {
int ier=7;
ier = smallFortran (8);
}
和匹配的Fortran:
function smallFortran(a) result(res) bind(c,name='smallFortran')
use ISO_C_BINDING
implicit none
integer(kind=c_int), intent(IN), value :: a
integer(kind=c_int) :: res
print *,'A = ', a
res = a;
endfunction smallFortran
有太多的事情会出错。。。。一个是C和Fortran通常使用不同的参数传递协议——C是按值传递的,Fortran通常(取决于编译器和其他问题)是按引用传递的。@HotLicks-Hmm,没有这样想过。也许我可以尝试传递int作为引用?(我的C不好,我会尝试作为一个指针,并通过引用)有太多的事情会出错。。。。一个是C和Fortran通常使用不同的参数传递协议——C是按值传递的,Fortran通常(取决于编译器和其他问题)是按引用传递的。@HotLicks-Hmm,没有这样想过。也许我可以尝试传递int作为引用?(我的C不好,我会尝试作为一个指针,并通过引用)@hotLicks评论让我注意到(现在看起来很明显,但我完全错过了。)谢谢!我现在正在尝试,并将公布我的结果。(为此苦苦挣扎了一段时间,所以我很期待得到回应。我不擅长C语言,也不熟悉C和fortran的混合,所以这可能就是我没有注意到的原因。:()谢谢!@hotLicks的评论让我注意到了这一点(现在似乎很明显,但我完全错过了。)谢谢!我现在正在尝试,并将发布我的结果。(为此我苦苦挣扎了一段时间,所以我很期待得到回应。我不擅长C,也不熟悉C和fortran的混合,所以这可能就是我没有注意到的原因。:()谢谢!