comp.lang.ada
 help / color / mirror / Atom feed
* Trying to pass strings to Fortan routines
@ 2001-08-12  4:54 Jack Scheible
  2001-08-12  5:24 ` tmoran
  2001-08-12 11:17 ` Dan Nagle
  0 siblings, 2 replies; 7+ messages in thread
From: Jack Scheible @ 2001-08-12  4:54 UTC (permalink / raw)


One of the promises of Ada was that one could use old libraries with the
Interfaces packages.  It's not going so well.  I have some old FORTRAN
libraries, and some of the routine accept CHARACTER*(*) arguments.  When
FORTRAN makes a subprogram call with one or more "string" arguments, it
passes the lengths of those strings as arguments _after_ all the
declared arguments.  I can get this to work with C.  So if I call

      SUBROUTINE SUB( S1, S2 )
      CHARACTER*(*) S1, S2

with the C statement

      sub_( s1, s2, strlen(s1), strlen(s2) );

All is well.  If I try the same thing in Ada (gnat), I get a Constraint
Error exception.

Actually, I get a Constraint Error if I just pass a String and anything
else.

Any ideas?

Thanks.

-jack




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Trying to pass strings to Fortan routines
  2001-08-12  4:54 Jack Scheible
@ 2001-08-12  5:24 ` tmoran
  2001-08-12 11:17 ` Dan Nagle
  1 sibling, 0 replies; 7+ messages in thread
From: tmoran @ 2001-08-12  5:24 UTC (permalink / raw)


> If I try the same thing in Ada (gnat), I get a Constraint Error exception.
  Would you mind showing us your code?  It clearly isn't literally
"the same thing" since Ada is a different language, and it isn't
semantically "the same thing" since then it would have worked the same.
"I guessed at a way to do it in Ada, but it didn't work" is not much
to go on.



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Trying to pass strings to Fortan routines
       [not found] <3B765238.6F013AD3@mail.verizon.net>
@ 2001-08-12  7:14 ` tmoran
  2001-08-12 15:28   ` Jack Scheible
  0 siblings, 1 reply; 7+ messages in thread
From: tmoran @ 2001-08-12  7:14 UTC (permalink / raw)


> int main(){
>   char filename[] = "test.out";
>   char str[] = "Testing...";
>   print_( filename, str, strlen(filename), strlen(str) );
> }

  Try:

with Interfaces.C;
procedure Main is

  procedure C_Print(Filename, Str : access Interfaces.C.Char;
                    Filename_Length, Str_Length: in Interfaces.C.Size_T);
  pragma Import(C, C_Print, "print_");

  procedure Print(Filename, Str : in String) is
    C_Filename: Interfaces.C.Char_Array := Interfaces.C.To_C(Filename);
    C_Str   : Interfaces.C.Char_Array := Interfaces.C.To_C(Str);
  begin
    C_Print(C_Filename(0)'Unchecked_Access, C_Str(0)'Unchecked_Access,
      Interfaces.C.Size_T(Filename'Length), Interfaces.C.Size_T(Str'Length));
  end Print;

begin
  Print("test.out", "Testing...");
end Main;



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Trying to pass strings to Fortan routines
  2001-08-12  4:54 Jack Scheible
  2001-08-12  5:24 ` tmoran
@ 2001-08-12 11:17 ` Dan Nagle
  1 sibling, 0 replies; 7+ messages in thread
From: Dan Nagle @ 2001-08-12 11:17 UTC (permalink / raw)


Hello,

Actually, the Fortran standard only says what a program has to be able
to do with character arguments, not how to pass them.  Popular
varieties of implementation include

-passing character, then length, for each character argument,
-passing character with all the lengths at the end
 of the calling sequence (which you have described in your post),
-and passing the address of a descriptor containing the address
 and length of the character argument.

Note that the size of the length argument can vary, if you've
got access to the documentation of the old Fortran compiler,
you may be able to guess the size of the length arguments.
Very few Fortran 77 compilers supported 4 billion character
long character variables, and you don't show what the "strlen"
macro? function? does...

Good luck!

-- 
Cheers!

Dan Nagle
Purple Sage Computing Solutions, Inc.

On Sun, 12 Aug 2001 04:54:59 GMT, Jack Scheible
<vze26j9s@mail.verizon.net> wrote:

>One of the promises of Ada was that one could use old libraries with the
>Interfaces packages.  It's not going so well.  I have some old FORTRAN
>libraries, and some of the routine accept CHARACTER*(*) arguments.  When
>FORTRAN makes a subprogram call with one or more "string" arguments, it
>passes the lengths of those strings as arguments _after_ all the
>declared arguments.  I can get this to work with C.  So if I call
>
>      SUBROUTINE SUB( S1, S2 )
>      CHARACTER*(*) S1, S2
>
>with the C statement
>
>      sub_( s1, s2, strlen(s1), strlen(s2) );
>
>All is well.  If I try the same thing in Ada (gnat), I get a Constraint
>Error exception.
>
>Actually, I get a Constraint Error if I just pass a String and anything
>else.
>
>Any ideas?
>
>Thanks.
>
>-jack




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Trying to pass strings to Fortan routines
  2001-08-12  7:14 ` Trying to pass strings to Fortan routines tmoran
@ 2001-08-12 15:28   ` Jack Scheible
  2001-08-12 18:17     ` tmoran
  0 siblings, 1 reply; 7+ messages in thread
From: Jack Scheible @ 2001-08-12 15:28 UTC (permalink / raw)


Hideous, but it works.
I don't like having to call a Fortran subroutine as though it were C, but it
works.

Thanks.

-jack

tmoran@acm.org wrote:

> > int main(){
> >   char filename[] = "test.out";
> >   char str[] = "Testing...";
> >   print_( filename, str, strlen(filename), strlen(str) );
> > }
>
>   Try:
>
> with Interfaces.C;
> procedure Main is
>
>   procedure C_Print(Filename, Str : access Interfaces.C.Char;
>                     Filename_Length, Str_Length: in Interfaces.C.Size_T);
>   pragma Import(C, C_Print, "print_");
>
>   procedure Print(Filename, Str : in String) is
>     C_Filename: Interfaces.C.Char_Array := Interfaces.C.To_C(Filename);
>     C_Str   : Interfaces.C.Char_Array := Interfaces.C.To_C(Str);
>   begin
>     C_Print(C_Filename(0)'Unchecked_Access, C_Str(0)'Unchecked_Access,
>       Interfaces.C.Size_T(Filename'Length), Interfaces.C.Size_T(Str'Length));
>   end Print;
>
> begin
>   Print("test.out", "Testing...");
> end Main;




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Trying to pass strings to Fortan routines
  2001-08-12 15:28   ` Jack Scheible
@ 2001-08-12 18:17     ` tmoran
  2001-08-13 18:28       ` Jack Scheible
  0 siblings, 1 reply; 7+ messages in thread
From: tmoran @ 2001-08-12 18:17 UTC (permalink / raw)


>Hideous, but it works.
>I don't like having to call a Fortran subroutine as though it were C, but it
>works.
  How does it differ from the method that got a Constraint_Error?
Perhaps some tweak to the latter would make it work.

In light of Dan Nagle's comment in <ppocntg7a1lqk4d2iatcd7hmt95269ubmr@4ax.com>

>Actually, the Fortran standard only says what a program has to be able
>to do with character arguments, not how to pass them.  Popular
>varieties of implementation include
>
>-passing character, then length, for each character argument,
>-passing character with all the lengths at the end
> of the calling sequence (which you have described in your post),
>-and passing the address of a descriptor containing the address
> and length of the character argument.

  Does your Gnat support Interfaces.Fortran in a way that matches your
Fortran compiler?  If so, that should be much easier.  If they don't
understand each other, they'll both have to speak some third way
that they do both understand.



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Trying to pass strings to Fortan routines
  2001-08-12 18:17     ` tmoran
@ 2001-08-13 18:28       ` Jack Scheible
  0 siblings, 0 replies; 7+ messages in thread
From: Jack Scheible @ 2001-08-13 18:28 UTC (permalink / raw)


I was importing the routines as Fortran, so when I tried to pass the
lengths of the strings, the compiler converted those to pointers,
since Fortran passes everything by reference.  Since C passes by
value, the Fortran routines now get the string lengths, not pointers
to the string lengths.

-jack

tmoran@acm.org wrote in message news:<MKzd7.57284$Kd7.32367559@news1.rdc1.sfba.home.com>...
> >Hideous, but it works.
> >I don't like having to call a Fortran subroutine as though it were C, but it
> >works.
>   How does it differ from the method that got a Constraint_Error?
> Perhaps some tweak to the latter would make it work.
> 
> In light of Dan Nagle's comment in <ppocntg7a1lqk4d2iatcd7hmt95269ubmr@4ax.com>
> 
> >Actually, the Fortran standard only says what a program has to be able
> >to do with character arguments, not how to pass them.  Popular
> >varieties of implementation include
> >
> >-passing character, then length, for each character argument,
> >-passing character with all the lengths at the end
> > of the calling sequence (which you have described in your post),
> >-and passing the address of a descriptor containing the address
> > and length of the character argument.
> 
>   Does your Gnat support Interfaces.Fortran in a way that matches your
> Fortran compiler?  If so, that should be much easier.  If they don't
> understand each other, they'll both have to speak some third way
> that they do both understand.



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2001-08-13 18:28 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <3B765238.6F013AD3@mail.verizon.net>
2001-08-12  7:14 ` Trying to pass strings to Fortan routines tmoran
2001-08-12 15:28   ` Jack Scheible
2001-08-12 18:17     ` tmoran
2001-08-13 18:28       ` Jack Scheible
2001-08-12  4:54 Jack Scheible
2001-08-12  5:24 ` tmoran
2001-08-12 11:17 ` Dan Nagle

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox