Thanks for the helpful hints from both the Ada (GNAT) and Pascal (GPC) lists. This Ada and gcc newbie and C don'twannabe appreciates it!
I now have examples of Ada main program calling Pascal and Pascal main program calling Ada. I hope this helps someone.
Here is the cleanest and best-looking example, putting together hints from both lists. To Waldek Hebisch, your method of "pchar" and "ppchar" also works and is really the same, but using System.Address looks a little more Ada-like. Thanks Jim Hopper for your input--I need to study up on "aliased".
Sorry for the cross-post.
Jerry
<Ada main program> with Ada.Text_IO; use Ada.Text_IO; with Ada.Command_Line; with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; with System;
procedure Ada_Calls_Pascal is
Gnat_argc : aliased Integer; pragma Import (C, Gnat_argc); Gnat_argv : System.Address; -- Just get the base address to argv, like C pragma Import (C, Gnat_argv);
Gnat_envp : System.Address; -- Same for envp. pragma Import (C, Gnat_envp);
procedure MyPascalProcedure (anInteger : Integer); pragma Import(Convention => C, Entity => MyPascalProcedure);
procedure p_initialize( Number_of_Arguments : Integer; Command_Vector, Environment_Variables : System.Address; Options : Integer); pragma Import(Convention => C, Entity => p_initialize, External_Name => "_p_initialize");
procedure init_pascal_main_program; pragma Import(Convention => C, Entity => init_pascal_main_program, External_Name => "_p__M0_init");
procedure p_finalize; pragma Import(Convention => C, Entity => p_finalize, External_Name => "_p_finalize");
Argument_Count_Plus_1 : Integer; Command_Name_String : String := Ada.Command_Line.Command_Name; -- C's argv[0]
begin Put_Line ("Hello from Ada_Calls_Pascal.");
-- Here is the "Ada way" of handling command line arguments. Argument_Count_Plus_1 := Ada.Command_Line.Argument_Count + 1; -- the usual C-style argc Put("Number of arguments counting the command name is "); Put(Argument_Count_Plus_1); New_Line;
Put_Line("Program is called " & Command_Name_String); Put_Line("Its arguments, if any, are:"); for Argument_Index in 1..Ada.Command_Line.Argument_Count loop Put_Line(Ada.Command_Line.Argument(Argument_Index)); -- C's argv[1...] end loop;
-- Show that we also can do things the "C way." Put("argc = "); Put(Gnat_argc); New_Line;
-- Initialize the Pascal runtime system before calling any Pascal routines. p_initialize (Gnat_argc, Gnat_argv, Gnat_envp, 0);
-- Initialize the user's Pascal main program. init_pascal_main_program;
-- Run a user Pascal procedure. MyPascalProcedure(42);
-- Finalize the Pascal world before leaving. p_finalize;
Put_Line ("Goodbye from Ada_Calls_Pascal."); end Ada_Calls_Pascal;
<Pascal called program> program MyPascalProgram(input, output);
{$gpc-main=dummy}
procedure MyPascalProcedure(anInteger : integer); attribute ( name = 'mypascalprocedure'); begin writeln('The integer from the Pascal procedure is: ', anInteger:1); end;
begin {When exported to Ada, this part should not be called.} writeln('In MyPascalProgram; error if calling from Ada.'); end.