Vax Fortran calling C subroutine, need to return a character string 
Author Message
 Vax Fortran calling C subroutine, need to return a character string

I am using Vax fortran and must call a C subroutine.  From this C
subroutine I have to return to the Fortran a character string.  How
can I do this?  I have tried issuing the Fortran subroutine call
using %ref...no luck.  And I have made an unsuccessful attempt at
using a common block/external variable.  That fails at link time.
Does anybody have any suggestions?  I would be grateful!  Thanks.

--
==================================================================

Eastman Kodak Company
Rochester, NY  14650-3041



Mon, 12 Jan 1998 03:00:00 GMT  
 Vax Fortran calling C subroutine, need to return a character string


Quote:
> I am using Vax Fortran and must call a C subroutine.  From this C
> subroutine I have to return to the Fortran a character string.  How
> can I do this?  I have tried issuing the Fortran subroutine call
> using %ref...no luck.  And I have made an unsuccessful attempt at
> using a common block/external variable.  That fails at link time.
> Does anybody have any suggestions?  I would be grateful!  Thanks.

        Long, VMS-specific answer sent  via  e-mail.  Short answer: make
    sure  you  null-terminate  the  Fortran  CHARACTER  variable  before
    passing it with %REF, and use INDEX(string,CHAR(0)) on return to see
    how much data the C subroutine wrote to the CHARACTER variable.

        ...Or make the C subroutine descriptor-aware...

            -Ken
--

 SLAC, P.O.Box 4349, MS 46  |  DECnet:   45537::FAIRFIELD (45537=SLACVX)
 Stanford, CA   94309       |  Voice:    415-926-2924    FAX: 415-926-3515
 -------------------------------------------------------------------------
 These opinions are mine, not SLAC's, Stanford's, nor the DOE's...



Tue, 13 Jan 1998 03:00:00 GMT  
 Vax Fortran calling C subroutine, need to return a character string

Quote:

>I am using Vax Fortran and must call a C subroutine.  From this C
>subroutine I have to return to the Fortran a character string.  How
>can I do this?  I have tried issuing the Fortran subroutine call
>using %ref...no luck.  And I have made an unsuccessful attempt at
>using a common block/external variable.  That fails at link time.
>Does anybody have any suggestions?  I would be grateful!  Thanks.

Depending on the nature of the C routine, you can use several
different techniques.  First thing to remember is that Fortran
uses fixed length, blank padded (on right), character strings.
Whereas C uses zero-byte terminated strings (and generally, no
blank padding in practice but the language does not prevent
someone from padding with blanks on the right).

Therefore, the first decision to make is to determine who, the
Fortran or the C code, handles the differences.  Let's say that
you cannot change the C code (e.g. its in a library you have no
source to), and it expects a C string pointer and returns a
pointer.  Such a C prototype would look something like:

     int mycode(char *src, char **ret);

In Fortran, you must do two things, convert the C string to a
zero terminated string and pass the arguments properly on the
call.

So, assuming that you are on VMS (I see VAX Fortran above), you
can use some of the STR$ routines for t{*filter*} the string to the
length of actual characters (not including the blank pads on the
right).  And, you can drop a zero into the last character
position plus one.  For example, suppose the character variable
length were 10 and it had two blanks padded on the right so the
actual number of characters is 8.  Thus, you can drop in the
zero byte doing the following:

             STRING(9:9) = CHAR(0)

If you don't want to modify your data, you can create a dummy
buffer called, BUFF such as in the following:

             BUFF = STRING
             BUFF(9:9) = CHAR(0)

And, of course, there are a myriad other ways to do this.

Now you need to properly pass the data, use the %REF on the
character variable that has the zero terminator, in this
case, BUFF...calling the routine mycode would be:

            mycode(%REF(BUFF),RETADR)

Now, RETADR is typed as an INTEGER*4 (for instance) and it will
be returned with a pointer (I am assuming 32 bit in this case).
To use this as a character string though requires some other
tricks as well as understanding descriptors.  So, lets build
a descriptor for this:

            INTEGER*4  DESCRIPTOR(2)

            DESCRIPTOR(1) = length
            DESCRIPTOR(2) = RETADR

Now, the length is a value you choose based on your approach
to this whole thing.  Normally, descriptors have other data
in the first location (type and class) but we can safely ignore
them in Fortran.  Let's assume that we say the length is 50.
Then, we create a dummy transfer routine like follows:

           SUBROUTINE TRANSFER(A,B)
           CHARACTER*(*) A,B
           J = LOCC(A,CHAR(0)) ! check arguments on this I am guessing
           B = A(1:J-1)
           RETURN

Now, you call this with the returned data as above,

           CHARACTER*50 RESULTSTRING

           CALL TRANSFER(DESCRIPTOR,RESULTSTRING)

So, what is happening.  The transfer function will search for the zero
terminator and return only the left most substring prior to the
zero terminator (of course, you should error check a bit too).  The
value is returned in RESULTSTRING which is a string for all
practical purposes to you.  The descriptor looks like a string inside
of the routine TRANSFER.

Now, I chose this problem since it covers all aspects of handling
strings between Fortran and C, there are many easier ways to do it but
hopefully you can figure them out from what I have written here.

Again, check out my approach, I am just writing from memory here of
things like LOCC and other functions but the descriptors are
right.

         phil



Sun, 18 Jan 1998 03:00:00 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. VAX Fortran call to Pascal subroutine

2. Dynamically linkable subroutines with VAX Fortran & VMS

3. VAX FORTRAN passing mech. for CHARACTER*1

4. RETURN character code in a STRING !

5. Character String Return Question

6. Fortran subroutine characters args and their lengths and C

7. returning local character string from python extension dll

8. Fortran subroutine to return #second

9. Functions that return character strings

10. VAX - passing strings between C and FORTRAN

11. Calling Fortran from C (VAX/VMS specific)

12. trouble calling fortran routine from C program on ultrix/Vax

 

 
Powered by phpBB® Forum Software