From: James Van Buskirk on
"Arjen Markus" <arjen.markus895(a)gmail.com> wrote in message
news:67c56fe1-7c2c-429f-8a3d-0c6206bd8496(a)w31g2000yqb.googlegroups.com...

> On Windows I get very different problems indeed. The one I want to
> tackle
> first is the problem with gfortran that I see:

Well, a big part of the problem is that you are trying to make it
work in 32-bit Windows, which gives you extra hoops to jump through.
I have an example that works in 64-bit Windows:

http://groups.google.com/group/comp.lang.fortran/msg/8b1f01ce0a7b035c?hl=en

I note that in your example you use C_LONG for the kind of Windows
handles and this is wrong: handles get promoted in 64-bit Windows, so
they should be C_INTPTR_T. I find the short list at

http://www.goprog.com/GoDevTool/GoasmHelp/64bits.htm#datat

to be useful. Anyhow, maybe if you try getting my example referenced
above to work on 32-bit Windows it might be easier since at this
point you know it works, just needs the magic words to get the STDCALL
convention and the right decoration.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


From: dpb on
Arjen Markus wrote:
....

> Yes, if you check the C header files, you will see LoadLibrary is
> redefined to LoadLibraryA or LoadLibraryW, depending on whatever
> branch
> the compiler has decided to use. (I first used LoadLibrary, but that
> obviously did not work ;)).
....

Oh, what about the case-matching??? You're not getting a translation to
uppercase by any chance, are you?

--
From: Arjen Markus on
On 5 jul, 16:03, "James Van Buskirk" <not_va...(a)comcast.net> wrote:
> "Arjen Markus" <arjen.markus...(a)gmail.com> wrote in message
>
> news:67c56fe1-7c2c-429f-8a3d-0c6206bd8496(a)w31g2000yqb.googlegroups.com...
>
> > On Windows I get very different problems indeed. The one I want to
> > tackle
> > first is the problem with gfortran that I see:
>
> Well, a big part of the problem is that you are trying to make it
> work in 32-bit Windows, which gives you extra hoops to jump through.
> I have an example that works in 64-bit Windows:
>
> http://groups.google.com/group/comp.lang.fortran/msg/8b1f01ce0a7b035c...
>
> I note that in your example you use C_LONG for the kind of Windows
> handles and this is wrong: handles get promoted in 64-bit Windows, so
> they should be C_INTPTR_T.  I find the short list at
>
> http://www.goprog.com/GoDevTool/GoasmHelp/64bits.htm#datat
>
> to be useful.  Anyhow, maybe if you try getting my example referenced
> above to work on 32-bit Windows it might be easier since at this
> point you know it works, just needs the magic words to get the STDCALL
> convention and the right decoration.
>
> --
> write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
> 6.0134700243160014d-154/),(/'x'/)); end

Changing the return type to C_INTPTR_T made no impression on the
linker.
In fact, it did not cause the compiler to complain either, whereas,
when I changed the binding name to '_LoadLibraryA@4', it did (first it
started about an invalid C name) - the kind c_intptr_t is not defined
in
my version of gfortran.

The STDCALL convention gives me a headache with Intel Fortran too,
making
it all very compiler- and platform dependent. But that is exactly one
of
the reasons I am trying to do this - create a platform-independent
interface.

Regards,

Arjen
From: James Van Buskirk on
"Arjen Markus" <arjen.markus895(a)gmail.com> wrote in message
news:c23711c4-f98a-41dc-bfd3-928c8e3b2c82(a)c33g2000yqm.googlegroups.com...

> Changing the return type to C_INTPTR_T made no impression on the
> linker.

That is to be expected for 32-bit Windows, where C_INTPTR_T and C_LONG
are equal.

> In fact, it did not cause the compiler to complain either, whereas,
> when I changed the binding name to '_LoadLibraryA@4', it did (first it
> started about an invalid C name) - the kind c_intptr_t is not defined
> in
> my version of gfortran.

There is supposed to be some way to get the name mangling right.
Check the gfortran mailing list or bug report list. C_INTPTR_T
has been there quite a while. If not misspelled in your test code
(did you USE ISO_C_BINDING appropriately?) try upgrading.

> The STDCALL convention gives me a headache with Intel Fortran too,
> making
> it all very compiler- and platform dependent. But that is exactly one
> of
> the reasons I am trying to do this - create a platform-independent
> interface.

Oh yes, I have an Intel example too, if that helps:

http://groups.google.com/group/comp.lang.fortran/msg/c0d2248673fb5238?hl=en

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


From: James Van Buskirk on
"James Van Buskirk" <not_valid(a)comcast.net> wrote in message
news:i0ssc7$vbd$1(a)news.eternal-september.org...

> There is supposed to be some way to get the name mangling right.
> Check the gfortran mailing list or bug report list. C_INTPTR_T
> has been there quite a while. If not misspelled in your test code
> (did you USE ISO_C_BINDING appropriately?) try upgrading.

OK, I got back from Exercise Period and found something in the bug
report list. Here is my modified version of makedll.f90:

C:\gfortran\clf\makedll>type makedll.f90
program makedll
use ISO_C_BINDING
implicit none
interface
function LoadLibrary(lpFileName) bind(C,name='LoadLibraryA')
use ISO_C_BINDING
implicit none
!GCC$ ATTRIBUTES STDCALL :: LoadLibrary
integer(C_INTPTR_T) LoadLibrary
character(kind=C_CHAR) lpFileName(*)
end function LoadLibrary
function GetLastError() bind(C,name='GetLastError')
use ISO_C_BINDING
implicit none
!GCC$ ATTRIBUTES STDCALL :: GetLastError
integer(C_LONG) GetLastError
end function GetLastError
function GetProcAddress(hModule, lpProcName)
bind(C,name='GetProcAddress')

use ISO_C_BINDING
implicit none
!GCC$ ATTRIBUTES STDCALL :: GetProcAddress
type(C_FUNPTR) GetProcAddress
integer(C_INTPTR_T), value :: hModule
character(kind=C_CHAR) lpProcName(*)
end function GetProcAddress
function simpson(f,a,b,n)
use ISO_C_BINDING
implicit none
real(C_double) simpson
interface
function f(x) bind(C)
use ISO_C_BINDING
implicit none
real(C_DOUBLE) f, x
end function f
end interface
real(C_DOUBLE) a, b
integer(C_INT) n
end function simpson
end interface
abstract interface
function dllfun(x)
use ISO_C_BINDING
implicit none
real(C_DOUBLE) dllfun, x
end function dllfun
end interface
integer(C_INTPTR_T) hmodule
integer(C_LONG) error
type(C_FUNPTR) FunAddress
procedure(dllfun), pointer :: fptr
real(C_DOUBLE) a, b
integer(C_INT) n
integer status

call system('del fun.*')
open(10,file='fun.f90',status='new')
write(10,'(a)') 'function fun(x) bind(C,name="fun")'
write(10,'(a)') ' use ISO_C_BINDING'
write(10,'(a)') ' implicit none'
write(10,'(a)') ' real(C_DOUBLE) fun, x'
write(10,'(a)') ''
write(10,'(a)') ' fun = x**2+3*x+2'
write(10,'(a)') 'end function fun'
close(10)
call system('gfortran fun.f90 -shared -ofun.dll', status)
write(*,'(a,i0)') 'status = ', status
if(status /= 0) stop
hmodule = LoadLibrary('fun.dll'//achar(0))
error = GetLastError()
write(*,'(a,z16.16)') 'hmodule = ', hmodule
if(hModule == 0) write(*,*) error
FunAddress = GetProcAddress(hmodule, 'fun'//achar(0))
error = GetLastError()
write(*,'(a,z16.16)') 'FunAddress = ',transfer(FunAddress,1_C_INTPTR_T)
if(.NOT.C_ASSOCIATED(FunAddress)) write(*,*) error
call C_F_PROCPOINTER(FunAddress, fptr)
a = 2
b = 3
n = 100
write(*,*) (b**3-a**3)/3+3*(b**2-a**2)/2+2*(b-a), simpson(fptr,a,b,n)
end program makedll

function simpson(f,a,b,n)
use ISO_C_BINDING
implicit none
real(C_double) simpson
interface
function f(x) bind(C)
use ISO_C_BINDING
implicit none
real(C_DOUBLE) f, x
end function f
end interface
real(C_DOUBLE) a, b
integer(C_INT) n
real(C_DOUBLE) h
integer(C_INT) i

h = (b-a)/n
simpson = f(a)
do i = 1, n-1
simpson = simpson+(3-(-1)**i)*f(a+i*h)
end do
simpson = simpson+f(b)
simpson = simpson*h/3
end function simpson

C:\gfortran\clf\makedll>del *.dll

C:\gfortran\clf\makedll>gfortran makedll.f90 -omakedll

C:\gfortran\clf\makedll>makedll
status = 0
hmodule = 000000006D5C0000
FunAddress = 000000006D5C11B4
15.833333333333334 15.833333333333339

C:\gfortran\clf\makedll>gfortran -v
Built by Equation Solution <http://www.Equation.com>.
Using built-in specs.
Target: i386-pc-mingw32
Configured with:
.../gcc-4.5-20090813-mingw/configure --host=i386-pc-mingw32 --bu
ild=x86_64-unknown-linux-gnu --target=i386-pc-mingw32 --prefix=/home/gfortran/gc
c-home/binary/mingw32/native/x86_32/gcc/4.5-20090813 --with-gcc --with-gnu-ld
--
with-gnu-as --disable-shared --disable-nls --disable-tls --with-gmp=/home/gfortr
an/gcc-home/binary/mingw32/native/x86_32/gmp --with-mpfr=/home/gfortran/gcc-home
/binary/mingw32/native/x86_32/mpfr --enable-languages=c,fortran,c++ --with-sysro
ot=/home/gfortran/gcc-home/binary/mingw32/cross/x86_32/gcc/4.5-20090813 --enable
-libgomp --enable-threads=win32 --disable-win32-registry
Thread model: win32
gcc version 4.5.0 20090813 (experimental) (GCC)

So all that was required to get it to work in 32-bit Windows was the

!GCC$ ATTRIBUTES STDCALL ::

statement in each Win32 function interface block. Of course we have
to check that this works in 64-bit Windows without modification:

C:\gfortran\clf\makedll>del *.dll

C:\gfortran\clf\makedll>gfortran makedll.f90 -omakedll

C:\gfortran\clf\makedll>makedll
status = 0
hmodule = 000000006D5C0000
FunAddress = 000000006D5C1420
15.833333333333332 15.833333333333341

C:\gfortran\clf\makedll>gfortran -v
Built by Equation Solution < http://www.Equation.com>.
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=c:/gcc_equation/bin/../libexec/gcc/x86_64-pc-mingw32/4.5.0/l
to-wrapper.exe
Target: x86_64-pc-mingw32
Configured with:
.../gcc-4.5-20091217-mingw/configure --host=x86_64-pc-mingw32 --
build=x86_64-unknown-linux-gnu --target=x86_64-pc-mingw32 --prefix=/home/gfortra
n/gcc-home/binary/mingw32/native/x86_64/gcc/4.5-20091217 --with-gmp=/home/gfortr
an/gcc-home/binary/mingw32/native/x86_64/gmp --with-mpfr=/home/gfortran/gcc-home
/binary/mingw32/native/x86_64/mpfr --with-mpc=/home/gfortran/gcc-home/binary/min
gw32/native/x86_64/mpc --with-sysroot=/home/gfortran/gcc-home/binary/mingw32/cro
ss/x86_64/gcc/4.5-20091217 --with-gcc --with-gnu-ld --with-gnu-as --disable-shar
ed --disable-nls --disable-tls --enable-libgomp --enable-languages=c,fortran,c++
--enable-threads=win32 --disable-win32-registry
Thread model: win32
gcc version 4.5.0 20091217 (experimental) (GCC)

So it works in both worlds. I think you should be able to make your
stuff go in gfortran and ifort, 32-bit and 64-bit Windows with
examples I have posted now. I can't help with Linux, but many others
can.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4
Prev: removing /save fortran compiler option
Next: Why not 0?