[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: How to call fortran subroution?
Thank you very much. I use IDL under windows.
I have generated vecadd.dll from visual fortran. Then I use
result = call_external('f:\fortran\vecadd.dll','f:\fortran\vecadd ', a,
n_elements(a), x, n_elements(x), b)
to call the dll. The error message is as following:
% CALL_EXTERNAL: Error loading sharable executable.
Symbol: f:\fortran\vecadd, File = f:\fortran\vecadd.dll
ERROR_PROC_NOT_FOUND
But I have dll file under f:\fortran. How to do then? May be I have set
wrong parameter.
This is explanation of call_external:
Result = CALL_EXTERNAL(Image, Entry [, P0, ..., PN-1])
Entry:A string containing the name of the symbol in the library which is the
entry point of the routine to be called.
I donot know how to set entry.
Where can I find The IDL External Development Guide?
Jiali
"Liam Gumley" <Liam.Gumley@ssec.wisc.edu> wrote in message
9bd2rb$cgm$1@news.doit.wisc.edu">news:9bd2rb$cgm$1@news.doit.wisc.edu...
> "Craig Markwardt" <craigmnet@cow.physics.wisc.edu> wrote in message
> onwv8m6xpf.fsf@cow.physics.wisc.edu">news:onwv8m6xpf.fsf@cow.physics.wisc.edu...
> > I think Stefano is right, you can't call FORTRAN directly from IDL,
> > especially with the CALL_EXTERNAL method. That method requires your
> > program to conform to a very specific interface for your function
> > parameters (two parameters named argc and argv).
> >
> > I'm looking at the External Development Guide for IDL 5.2. They
> > recommend a "wrapper" function written in C, which in turn calls the
> > FORTRAN. That manual does give an example where the FORTRAN
> > subroutine can be called directly, but the semantics appear to be
> > present only on a few platforms (VMS or IBM AIX), and the subroutine
> > must still conform to the argc and argv convention.
> >
> > Questions:
> > * What example are you looking at?
> > * Does Ronn Kling's book on external linking address FORTRAN?
>
> If your Fortran compiler supports the %VAL and LOC extensions, you can
call
> a Fortran subroutine or function from IDL via CALL_EXTERNAL using a
Fortran
> wrapper. I developed the routines shown below to vectorize the following
> operation in IDL:
>
> for i = 0L, n_elements(x) - 1L do a[x[i]] = a[x[i]] + b[i]
>
> ---begin vecadd.f---
> c ... This is the wrapper routine called by IDL
> subroutine vecadd(argc, argv)
> integer*4 argc, argv(*), j
> j = loc(argc)
> call vecadd1(%val(argv(1)), %val(argv(2)), %val(argv(3)),
> & %val(argv(4)), %val(argv(5)))
> end
>
> c ... This is the routine which does the work.
> c ... The arguments are defined exactly the same way as in the
> c ... call to CALL_EXTERNAL in vecadd.pro
> subroutine vecadd1(a, na, x, nx, b)
> integer*4 na, nx
> real*4 a(na), b(nx)
> integer*4 x(nx), i
> do i = 1, nx
> a(x(i)) = a(x(i)) + b(i)
> end do
> end
> ---end vecadd.f
>
> ---begin vecadd.pro---
> FUNCTION VECADD, ARRAY, INDEX, VALUE
>
> ;- Check arguments
> if (n_elements(array) eq 0) then $
> message, 'Argument A is undefined'
> if (n_elements(index) eq 0) then $
> message, 'Argument X is undefined'
> if (n_elements(value) eq 0) then $
> message, 'Argument B is undefined'
> if (n_elements(index) ne n_elements(value)) then $
> message, 'Arguments X and B must have the same number of elements'
>
> ;- Create copies of the arguments with correct type
> if (size(a, /tname) ne 'FLOAT') then begin
> a = float(array)
> endif else begin
> a = array
> endelse
> x = ((long(index) > 0L) < (n_elements(a) - 1L)) + 1L
> b = float(value)
>
> ;- Call the external routine
> result = call_external('vecadd.so', 'vecadd_', $
> a, n_elements(a), x, n_elements(x), b)
> if (result ne 1) then message, 'Error calling external routine'
>
> ;- Return result
> return, a
>
> END
> ---end vecadd.pro---
>
> To compile the Fortran source on SGI IRIX 6.5:
> % f77 -n32 -KPIC -c vecadd.f
> % ld -n32 -shared -o vecadd.so vecadd.o
> (see /usr/local/rsi/idl_5.3/external/call_external/Fortran/Makefile for
the
> syntax on other UNIX platforms).
>
> To call the routine in IDL 5.3:
> a = findgen(10)
> x =[3, 5, 7]
> b = [2, 4, 6]
> print, vecadd(a, x, b), format='(10f5.1)'
> 0.0 1.0 2.0 5.0 4.0 9.0 6.0 13.0 8.0 9.0
>
> The IDL External Development Guide is quite helpful in explaining how this
> works.
>
> Cheers,
> Liam.
> http://cimss.ssec.wisc.edu/~gumley/
>
>
>