comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: How to access this package written in C?
Date: Wed, 21 Apr 2010 19:39:23 +0200
Date: 2010-04-21T19:39:20+02:00	[thread overview]
Message-ID: <1ccis7uwsta0r$.1qvwug3z3f1sk$.dlg@40tude.net> (raw)
In-Reply-To: 4e9d2aaf-c0a6-4798-b838-8f5b7c4a39d1@k33g2000yqc.googlegroups.com

On Wed, 21 Apr 2010 09:43:02 -0700 (PDT), resander wrote:

> I am working on software that manipulates SQL databases via a GUI. It
> is written in C or C++ without classes and compiled on Linux. Would
> also want it to run on Windows eventually. This software has
> essentially one entry procedure:
> 
>   int guidb ( int appno , int recaddress );  // in C

This is awful even on C standards.

> which returns an outcome as an int, takes an int appno which specifies
> application and an address of a record in recaddress. The latter is
> used for passing the memory address of any recordtype variable and is
> cast to a byte address inside guidb.

[...]

> Desired use in Ada (same as above):
> 
> type PRODUCT is RECORD int prodcode; float price; char descr
> [50]...END RECORD;
> 
> procedure getproduct ( p : out PRODUCT ; result : out int ) is
> begin
>    result = guidb ( 0 , address_of(p) how ??? ) ;
> end
> 
> prod : PRODUCT;
> outcome : int ;

[...]

> How to do this in in Ada? If it cannot be done, can the interface
> above be changed to make it possible?

Make it a generic function:

   SQL_Error : exception;
   
   generic
      type Data_Type is private;
   function Generic_Get (No : Integer) return Data_Type;

The implementation of:
   
   with Ada.Exceptions;  use Ada.Exceptions;
   with Interfaces.C;    use Interfaces.C;

   function Generic_Get (No : Integer) return Data_Type is
      function Internal (No : int; Data : access Data_Type) return int;
      pragma Import (C, Internal, "guilib");
      Data   : aliased Data_Type;
      Result : int;
   begin
      Result := Internal (int (No), Data'Access);
      if Result /= 0 then
         Raise_Exception
         (SQL_Error'Identity, "Error code:" & int'Image (Result));
      else
         return Data;
      end if;
   end Generic_Get;

Declare a type you need, e.g. Product:

   type Product is record
      Code : int;
      Price  : float;
      Descr : char_array (1..50);
   end record;
   pragma Convention (C, Product); -- Note this pragma!

Instantiate the function:

   function Get is new Generic_Get (Product);

Use it as:

   X : Product := Get (0);

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



  reply	other threads:[~2010-04-21 17:39 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-04-21 16:43 How to access this package written in C? resander
2010-04-21 17:39 ` Dmitry A. Kazakov [this message]
2010-04-22 20:12 ` Björn Persson
2010-04-22 21:12 ` Keith Thompson
2010-04-23 12:58   ` resander
2010-04-23 14:15     ` Dmitry A. Kazakov
2010-04-23 14:44     ` John B. Matthews
2010-04-23 15:39       ` John B. Matthews
2010-04-26 18:16     ` Robert A Duff
2010-04-26 19:57       ` Keith Thompson
2010-04-26 21:20         ` Maciej Sobczak
2010-04-27  6:52           ` Alex R. Mosteo
2010-04-27 22:29             ` Randy Brukardt
2010-05-03  8:12               ` Alex R. Mosteo
2010-04-27  0:20         ` Robert A Duff
2010-04-27  1:01           ` Keith Thompson
2010-04-27 16:07             ` Robert A Duff
2010-04-27 22:29               ` Randy Brukardt
2010-04-27  1:31           ` Randy Brukardt
replies disabled

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