- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ihave a problem when call Fortran function from c using bind (c), e.g.
Fortran function(mean.f90):
real, function mean(x)
real,dimension(:),intent(in) :: x
integer :: n
n=size(x)
mean=0.
do i=1,n
mean=mean+x(i)
enddo
mean=mean/real(n)
end function mean
communication function between c and fortran (c_mean.f90):
real(c_float), function c_mean(n,x) bind(c)
use, intrinsic :: iso_c_binding
integer(c_int),intent(in),value :: n
real(c_float), intent(in) :: x(n)
c_mean=mean(x)
end function c_mean
c program to call communication function (test.c)
#include
#include
float c_mean(int n, float *x);
main() {
float Y,x[10];
int i;
for (i=0; i<10; i++) {
x=i;
}
Y=c_mean1(10,x);
return 0;
}
compile and link in IVF and VC:
ifort mean.f90 c_mean.f90 /c
cl test.c mean.obj c_mean.obj
will give test.exe out.
but when I run test.exe there is an error window popup. I know the reason is that I used
"real,dimension(:),intent(in) :: x" in the mean.f90. If I use mean(n,x) as the fortran function, there is no this problem.
Thus my question is: can I call Fortran functions like mean.f90 from c? If I can, how do I change my c/fortran codes?
Thanks!
Addison
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ihave a problem when call Fortran function from c using bind (c), e.g.
Fortran function(mean.f90):
real, function mean(x)
real,dimension(:),intent(in) :: x
communication function between c and fortran (c_mean.f90):
real(c_float), function c_mean(n,x) bind(c)
c_mean=mean(x)
end function c_mean
but when I run test.exe there is an error window popup. I know the reason is that I used
"real,dimension(:),intent(in) :: x" in the mean.f90. If I use mean(n,x) as the fortran function, there is no this problem.
Thus my question is: can I call Fortran functions like mean.f90 from c? If I can, how do I change my c/fortran codes?
You don't have a C<->Fortran problem; you actually have a Fortran<->Fortran problem.
Search for "Explicit interfaces" in your IVF online help, and find the page "Determining When Procedures Require Explicit Interfaces". The second item reads "A dummy argument that is an assumed-shape array".
Explicit interfaces are a very important concept in Fortran-90, so please read it thoroughly. Experienced Fortran-9x programmers tend to use them always (even when not strictly needed), because they ensure correct calling sequence between the calling and called procedures.
The best method to provide an explicit interface is USE association, i.e. to put the callee in a module, and let the caller USE that module. The following Fortran code will work as expected (when your syntax errors are fixed):
[cpp]module m_test !================================================= contains !================================================= real function mean(x) real,dimension(:),intent(in) :: x integer :: n n=size(x) mean=0. do i=1,n mean=mean+x(i) enddo mean=mean/real(n) end function mean end module m_test !================================================= real(c_float) function c_mean(n,x) bind(c) use, intrinsic :: iso_c_binding USE M_TEST integer(c_int),intent(in),value :: n real(c_float), intent(in) :: x(n) c_mean=mean(x) end function c_mean[/cpp]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You don't have a C<->Fortran problem; you actually have a Fortran<->Fortran problem.
Search for "Explicit interfaces" in your IVF online help, and find the page "Determining When Procedures Require Explicit Interfaces". The second item reads "A dummy argument that is an assumed-shape array".
Explicit interfaces are a very important concept in Fortran-90, so please read it thoroughly. Experienced Fortran-9x programmers tend to use them always (even when not strictly needed), because they ensure correct calling sequence between the calling and called procedures.
The best method to provide an explicit interface is USE association, i.e. to put the callee in a module, and let the caller USE that module. The following Fortran code will work as expected (when your syntax errors are fixed):
[cpp]module m_test !================================================= contains !================================================= real function mean(x) real,dimension(:),intent(in) :: x integer :: n n=size(x) mean=0. do i=1,n mean=mean+x(i) enddo mean=mean/real(n) end function mean end module m_test !================================================= real(c_float) function c_mean(n,x) bind(c) use, intrinsic :: iso_c_binding USE M_TEST integer(c_int),intent(in),value :: n real(c_float), intent(in) :: x(n) c_mean=mean(x) end function c_mean[/cpp]
Thanks. It work now.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You don't have a C<->Fortran problem; you actually have a Fortran<->Fortran problem.
Search for "Explicit interfaces" in your IVF online help, and find the page "Determining When Procedures Require Explicit Interfaces". The second item reads "A dummy argument that is an assumed-shape array".
Explicit interfaces are a very important concept in Fortran-90, so please read it thoroughly. Experienced Fortran-9x programmers tend to use them always (even when not strictly needed), because they ensure correct calling sequence between the calling and called procedures.
The best method to provide an explicit interface is USE association, i.e. to put the callee in a module, and let the caller USE that module. The following Fortran code will work as expected (when your syntax errors are fixed):
[cpp]module m_test !================================================= contains !================================================= real function mean(x) real,dimension(:),intent(in) :: x integer :: n n=size(x) mean=0. do i=1,n mean=mean+x(i) enddo mean=mean/real(n) end function mean end module m_test !================================================= real(c_float) function c_mean(n,x) bind(c) use, intrinsic :: iso_c_binding USE M_TEST integer(c_int),intent(in),value :: n real(c_float), intent(in) :: x(n) c_mean=mean(x) end function c_mean[/cpp]
Thanks. It works now.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page