Passing string from IDL to Fortran [message #90466] |
Tue, 03 March 2015 11:15  |
Sir Loin Steak
Messages: 42 Registered: January 2012
|
Member |
|
|
Hi all,
I am calling a Fortran subroutine from IDL, and it has been set up in a way that the filepath to some data is passed in via the argument list. So, in the subroutine we have:
character*(*),intent(in) :: dset ! path to datafiles
I initially just passed the string as normal from IDL via the call_external routine, which didn't work. Then I read it should be converted to byte before being used, so I did:
filepath = '/path_to_files/'
byte_filepath = byte(filepath)
and then passed byte_filepath via call_external to the Fortran subroutine. However, this doesn't work either (from the Fortran routine when I do print*, len_trim(dset) it gives a value of 0).
Can anyone offer any help? I have searched online and on this newsgroup and it seems to be a common query, but one which I can find no answer to. I don't need to alter the filepath or anything in Fortran - I just want to specify it in IDL and then pass it to Fortran.
For now I have just hardcoded the filepath into the Fortran routine and deleted it from the argument list, but I would like to know how to get it done using call_external. (I'm using Red Hat if that makes a difference to the solution).
Cheers,
Liam
|
|
|
Re: Passing string from IDL to Fortran [message #90481 is a reply to message #90466] |
Wed, 04 March 2015 11:50  |
Jim Pendleton
Messages: 165 Registered: November 2011
|
Senior Member |
|
|
On Tuesday, March 3, 2015 at 12:15:47 PM UTC-7, jf22901 wrote:
> Hi all,
>
> I am calling a Fortran subroutine from IDL, and it has been set up in a way that the filepath to some data is passed in via the argument list. So, in the subroutine we have:
>
> character*(*),intent(in) :: dset ! path to datafiles
>
> I initially just passed the string as normal from IDL via the call_external routine, which didn't work. Then I read it should be converted to byte before being used, so I did:
>
> filepath = '/path_to_files/'
> byte_filepath = byte(filepath)
>
> and then passed byte_filepath via call_external to the Fortran subroutine. However, this doesn't work either (from the Fortran routine when I do print*, len_trim(dset) it gives a value of 0).
>
> Can anyone offer any help? I have searched online and on this newsgroup and it seems to be a common query, but one which I can find no answer to. I don't need to alter the filepath or anything in Fortran - I just want to specify it in IDL and then pass it to Fortran.
>
> For now I have just hardcoded the filepath into the Fortran routine and deleted it from the argument list, but I would like to know how to get it done using call_external. (I'm using Red Hat if that makes a difference to the solution).
>
> Cheers,
>
> Liam
It's been years since I used any of the Fortran 90 features and the "slick" way to do it probably depends a lot on the particular compiler you're using.
The "simple" way will generally involve passing the data as a fixed-length byte array, also declared as a byte vector of fixed length in Fortran. Then you'd perform a bytewise data copy or an equivalence between byte vector and a string of fixed length. Back in the VMS Fortran days I'd use %val() and %loc() for some of this work.
Also make sure you're using the correct VALUE keyword flags on your CALL_EXTERNAL. Most likely you will want to pass the address of the first byte of characters in your string or byte array, and not the address of the IDL_String descriptor (See the External Development Guide) if you insist on using an IDL String. However if you do pass the IDL_String it will contain other information you need to tell Fortran, such as the string's actual length. Fortran isn't going to know, just from an address, how long the string is - unless Fortran has gone all C and started sticking NULLs at the end - that would be an abomination!
Exercises left for the reader.
Jim P.
"I Still Work For Exelis, but the abomination comments are my own"
Jim P.
|
|
|