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;
next 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