From: glen herrmannsfeldt on
James Van Buskirk <not_valid(a)comcast.net> wrote:
(snip)

> interface
> subroutine qsort(base, nmemb, size, compar) bind(C,name='qsort')
> use ISO_C_BINDING
> implicit none
> type(C_PTR), value :: base
> integer(C_SIZE_T), value :: nmemb
> integer(C_SIZE_T), value :: size
> type(C_FUNPTR), value :: compar
> end subroutine qsort
> end interface

OK, I forgot the value on the type(C_FUNPTR).
As usual, it works fine if you just pass the function name in
the usual Fortran way, and not by value.

I tend to write my C calls with arrays without C_LOC(), and
without value, which I believe is also supposed to work.
Though if you use C_LOC(), then the array has to have the TARGET
attribute, where if you just pass it as an array, it doesn't.

It seems that C_SIZEOF() didn't come until Fortran 2008, and
isn't in the gfortran that I am using. I then tried
C_LOC(X(2))-C_LOC(X(1)) which fails, as you can't subtract C_PTR
values. So I just use 4, instead.


! attempt to sort using C qsort
use, intrinsic:: iso_C_binding
integer, target :: x(10)
data x/1,4,3,8,2,6,9,7,0,5/
interface
subroutine qsort(array,n,m,compar) bind(c)
use, intrinsic:: iso_C_binding
type(c_ptr), value :: array
integer(c_size_t) ,value:: m, n
type(c_funptr), value :: compar
end subroutine
integer function icmp(a,b) bind(c)
use, intrinsic:: iso_C_binding
integer :: a,b
end function
end interface
call qsort(c_loc(x),10,4,c_funloc(icmp))
print *,x
end
!
integer function icmp(a,b) bind(C)
if(a.gt.b) then
icmp=1
else if(a.lt.b) then
icmp=-1
else
icmp=0
endif
return
end


-- glen