Prev: removing /save fortran compiler option
Next: Why not 0?
From: Ian Harvey on 5 Jul 2010 16:02 On 5/07/2010 10:35 PM, Arjen Markus wrote: > On 5 jul, 13:52, Ian Harvey<ian_har...(a)bigpond.com> wrote: >> >> You're on win32? If so, then system API's don't use the C calling >> convention. gfortran has a compiler directive that may help. >> >>> use iso_c_binding >> >> !GCC$ ATTRIBUTES STDCALL :: c_load_library >> >>> character(kind=c_char), dimension(*) :: cname > > Unfortunately, this does not work! > > The error message remains the same, I have tried with c_load_library, > LoadLibraryA and LoadLibraryA@4 - always the same message. > > I use version 4.4.3 of gfortran at the moment. > > Regards, > > Arjen Works for me with a 4.6 from mid May.
From: Arjen Markus on 6 Jul 2010 03:10 On 5 jul, 20:50, "James Van Buskirk" <not_va...(a)comcast.net> wrote: > "James Van Buskirk" <not_va...(a)comcast.net> wrote in messagenews: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 Not sure what was the actual solution, but I am using gfortran 4.5.0 now and it is working fine :). Including the c_intptr_t kind. This leaves me with the combination Intel Fortran/Windows XP to sort out. And to get the platform-independent API that I set out for. At least it is partially working, thank you all. Regards, Arjen
From: Arjen Markus on 7 Jul 2010 03:46 On 6 jul, 09:10, Arjen Markus <arjen.markus...(a)gmail.com> wrote: > On 5 jul, 20:50, "James Van Buskirk" <not_va...(a)comcast.net> wrote: > > > > > > > "James Van Buskirk" <not_va...(a)comcast.net> wrote in messagenews: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 > > Not sure what was the actual solution, but I am using gfortran 4.5.0 > now and > it is working fine :). Including the c_intptr_t kind. > > This leaves me with the combination Intel Fortran/Windows XP to sort > out. > And to get the platform-independent API that I set out for. > > At least it is partially working, thank you all. > > Regards, > > Arjen- Tekst uit oorspronkelijk bericht niet weergeven - > > - Tekst uit oorspronkelijk bericht weergeven - I am not quite sure why I had such trouble getting this all to work on Windows and Intel Fortran, but right now it is working fine on three different platforms: - Windows + Intel Fortran - Windows + (MinGW version of) gfortran - Linux + Intel Fortran (but I expect gfortran to work as well, just have not got a recent enough version yet) (This will become part of my Flibs project - http://flibs.sf.net) Regards, Arjen
From: fj on 7 Jul 2010 14:23 On 7 juil, 09:46, Arjen Markus <arjen.markus...(a)gmail.com> wrote: > On 6 jul, 09:10, Arjen Markus <arjen.markus...(a)gmail.com> wrote: > > > > > On 5 jul, 20:50, "James Van Buskirk" <not_va...(a)comcast.net> wrote: > > > > "James Van Buskirk" <not_va...(a)comcast.net> wrote in messagenews: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 > > > Not sure what was the actual solution, but I am using gfortran 4.5.0 > > now and > > it is working fine :). Including the c_intptr_t kind. > > > This leaves me with the combination Intel Fortran/Windows XP to sort > > out. > > And to get the platform-independent API that I set out for. > > > At least it is partially working, thank you all. > > > Regards, > > > Arjen- Tekst uit oorspronkelijk bericht niet weergeven - > > > - Tekst uit oorspronkelijk bericht weergeven - > > I am not quite sure why I had such trouble getting this all to work > on Windows and Intel Fortran, but right now it is working fine on > three different platforms: > - Windows + Intel Fortran > - Windows + (MinGW version of) gfortran > - Linux + Intel Fortran (but I expect gfortran to work as well, just > have not got a recent enough version yet) > (This will become part of my Flibs project -http://flibs.sf.net) > > Regards, > > Arjen Nice ! I had planned to make a very similar development. I already use your cgi-protocol module from Flibs. I hope to test this new development before the end of the year. Regards. F. Jacq
From: Arjen Markus on 8 Jul 2010 07:33
On 7 jul, 20:23, fj <francois.j...(a)irsn.fr> wrote: > On 7 juil, 09:46, Arjen Markus <arjen.markus...(a)gmail.com> wrote: > > > > > > > On 6 jul, 09:10, Arjen Markus <arjen.markus...(a)gmail.com> wrote: > > > > On 5 jul, 20:50, "James Van Buskirk" <not_va...(a)comcast.net> wrote: > > > > > "James Van Buskirk" <not_va...(a)comcast.net> wrote in messagenews: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 > > > > Not sure what was the actual solution, but I am using gfortran 4.5.0 > > > now and > > > it is working fine :). Including the c_intptr_t kind. > > > > This leaves me with the combination Intel Fortran/Windows XP to sort > > > out. > > > And to get the platform-independent API that I set out for. > > > > At least it is partially working, thank you all. > > > > Regards, > > > > Arjen- Tekst uit oorspronkelijk bericht niet weergeven - > > > > - Tekst uit oorspronkelijk bericht weergeven - > > > I am not quite sure why I had such trouble getting this all to work > > on Windows and Intel Fortran, but right now it is working fine on > > three different platforms: > > - Windows + Intel Fortran > > - Windows + (MinGW version of) gfortran > > - Linux + Intel Fortran (but I expect gfortran to work as well, just > > have not got a recent enough version yet) > > (This will become part of my Flibs project -http://flibs.sf.net) > > > Regards, > > > Arjen > > Nice ! I had planned to make a very similar development. I already use > your cgi-protocol module from Flibs. I hope to test this new > development before the end of the year. > > Regards. > > F. Jacq- Tekst uit oorspronkelijk bericht niet weergeven - > > - Tekst uit oorspronkelijk bericht weergeven - Good to hear that :). If you have any ideas for improvement, let me know. Now that everything (for a suitably modest value of "every") is working, I can expand it quickly. For instance: As a user you do not want to have to consider things like one or more underscores or lower/uppercase when loading a routine by name. So I want to hide that sort of complexities. Regards, Arjen |