Prev: removing /save fortran compiler option
Next: Why not 0?
From: James Van Buskirk on 5 Jul 2010 10:03 "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 5 Jul 2010 10:11 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 5 Jul 2010 10:28 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 5 Jul 2010 11:05 "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 5 Jul 2010 14:50 "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? |