comp.lang.ada
 help / color / mirror / Atom feed
From: "Eric G. Miller" <egm2@jps-nospam.net>
Subject: Interfacing to C library...
Date: Fri, 01 Nov 2002 15:38:04 GMT
Date: 2002-11-01T15:38:04+00:00	[thread overview]
Message-ID: <pan.2002.11.01.15.38.12.168069@jps-nospam.net> (raw)


I'm working on building an interface to a C library where most of the
functions are defined as returning a long integer containing the various
error codes returned by each function and data is passed back from the
"functions" via pointer arguments to [usually] structures.  Below is
something of a demonstration of what I've come up with, but I'd appreciate
pointers to better approaches.  Eventually, I'd like to hide the access
type and handle the error codes another way (exceptions maybe...).


/************************* "cfuncs.h" **************************/
#ifndef CFUNCS_H
#define CFUNCS_H

/* error codes, might be multiples via |= */
#define NO_PROBLEMS       0x0000
#define DID_NOT_WORK      0x0001
#define FAILED_MISERABLY  0x0002
#define NASAL_DEMONS      0x0004

typedef struct scores_structure {
	long wins;
	long losses;
} Score_Type;

typedef enum game_names_enum {
	Pin_the_Tail_on_the_Donkey,
	Hop_Scotch,
	Dodge_Ball,
	Television_Tag,
	Kill_the_Man
} Game_Name_Type;

typedef struct game_play_structure {
	Game_Name_Type game;
	Score_Type     scores;
} Game_Type;


long Initialize_Game (Game_Type *Game      /* (in out) The game keeper */
		     ,Game_Name_Type Type  /* (in)     The game type   */
		);

long Play_Game (Game_Type *Game);  /* (in out) Plays the game */

#endif
/*****************************************************************/
\f
/*************************** "cfuncs.c" **************************/
#include <stdlib.h>
#include <time.h>
#include "cfuncs.h"

long Initialize_Game (Game_Type *Game      /* (out) The game keeper */
		     ,Game_Name_Type Type  /* (in)     The game type   */
		)
{
    long status = NO_PROBLEMS;

    if (!Game)
    {
        status |= NASAL_DEMONS;
    }
    else if (Type < Pin_the_Tail_on_the_Donkey || Type > Kill_the_Man)
    {
	status |= FAILED_MISERABLY;
    }
    else
    {
	srand (time(NULL));
	Game->game = Type;
	Game->scores.wins = 0;
	Game->scores.losses = 0;
    }
    return status;
}
	

long Play_Game (Game_Type *Game)  /* (in out) Plays the game */
{
    long status = NO_PROBLEMS;

    if (!Game)
    {
	status |= NASAL_DEMONS;
    }
    else
    {
	int number = rand();
	number >>= 4;
	if (number & 1)
	    Game->scores.wins++;
	else
	    Game->scores.losses++;
    }
    return status;
}
/*****************************************************************/
\f
-- cfuncs.ads
--
-- Interface to cfuncs "game"

package c_funcs is
    -- Error Type
    type Error_Code is mod 2**32;
    -- Error codes
    No_Problems      : constant Error_Code := 16#0000#;
    Did_Not_Work     : constant Error_Code := 16#0001#;
    Failed_Miserably : constant Error_Code := 16#0002#;
    Nasal_Demons     : constant Error_Code := 16#0004#;
    
    type Game_Name_Type is (
            Pin_the_Tail_on_the_Donkey,
            Hop_Scotch,
            Dodge_Ball,
            Television_Tag,
            Kill_the_Man
            );

    pragma Convention (Convention => C,
                       Entity     => Game_Name_Type);

    type Score_Type is
        record
            Wins   : Long_Integer;
            Losses : Long_Integer;
        end record;
        
    pragma Convention (Convention => C,
                       Entity     => Score_Type);
                   
    type Game_Type is
        record
            Game   : Game_Name_Type;
            Scores : Score_Type;
        end record;

    type Game_Type_Ptr is access all Game_Type;

    pragma Convention (Convention => C,
                       Entity     => Game_Type);
                   
    function Initialize_Game (
        Game  : Game_Type_Ptr;
        Name  : Game_Name_Type
        ) return Error_Code;

    function Play_Game (
        Game  : Game_Type_Ptr
        ) return Error_Code;

    pragma Import (Convention    => C,
                   Entity        => Initialize_Game,
                   External_Name => "Initialize_Game");
    
    pragma Import (Convention    => C,
                   Entity        => Play_Game,
                   External_Name => "Play_Game");
                   
end c_funcs;
\f
-- funky_test.adb
with Ada.Text_Io; use Ada.Text_Io;
with C_Funcs; use C_Funcs;

procedure Funky_Test 
is
    Game  : Game_Type_Ptr;
    Error : Error_Code;

    procedure Check_Errors (Error : Error_Code)
    is
    begin
    	if (Error and Did_Not_Work) /= 0 then
	    Put_Line ("Got 'Did_Not_Work' Error!");
	end if;
	if (Error and Failed_Miserably) /= 0 then
	    Put_Line ("Got 'Failed_Miserably' Error!");
	end if;
	if (Error and Nasal_Demons) /= 0 then
	    Put_Line ("Got 'Nasal_Demons' Error!");
	end if;
	if Error /= No_Problems then
	    raise Program_Error;
	end if;
    end Check_Errors;
    
    procedure Print_Scores (Game : in Game_Type_Ptr)
    is
    begin
    	Put_Line (Game_Name_Type'Image(Game.Game) & 
	     ": Won "  & Long_Integer'Image(Game.Scores.Wins) &
	     ": Lost " & Long_Integer'Image(Game.Scores.Losses));
    end Print_Scores;
    
begin
    Game := new Game_Type;
    Error := Initialize_Game (Game => Game, Name => Pin_the_Tail_on_the_Donkey);
    Check_Errors (Error);
    Error := Play_Game (Game);
    Check_Errors (Error);
    Error := Play_Game (Game);
    Check_Errors (Error);
    Error := Play_Game (Game);
    Check_Errors (Error);
    Error := Play_Game (Game);
    Check_Errors (Error);
    Error := Play_Game (Game);
    Check_Errors (Error);
    Error := Play_Game (Game);
    Check_Errors (Error);
    Error := Play_Game (Game);
    Check_Errors (Error);
    Print_Scores (Game);

    Error := Initialize_Game (Game => Game, Name => Dodge_Ball);
    Check_Errors (Error);
    Error := Play_Game (Game);
    Check_Errors (Error);
    Error := Play_Game (Game);
    Check_Errors (Error);
    Error := Play_Game (Game);
    Check_Errors (Error);
    Error := Play_Game (Game);
    Check_Errors (Error);
    Print_Scores (Game);

end Funky_Test;





             reply	other threads:[~2002-11-01 15:38 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-11-01 15:38 Eric G. Miller [this message]
2002-11-01 17:11 ` Interfacing to C library Robert A Duff
2002-11-01 17:40   ` tmoran
2002-11-02  5:10     ` Eric G. Miller
2002-11-02  6:02       ` tmoran
2002-11-02 16:10       ` Robert A Duff
2002-11-02 18:35         ` Eric G. Miller
2002-11-02 18:55           ` Robert A Duff
2002-11-02 23:59             ` Eric G. Miller
2002-11-03 16:47               ` Robert A Duff
2002-11-03 18:55                 ` Eric G. Miller
2002-11-03  9:28             ` Dale Stanbrough
replies disabled

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