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.