comp.lang.ada
 help / color / mirror / Atom feed
From: Georg Bauhaus <rm.dash-bauhaus@futureapps.de>
Subject: Re: Thick bindings to a C library and gnattest: suggestions?
Date: Tue, 02 Jul 2013 10:55:39 +0200
Date: 2013-07-02T10:55:34+02:00	[thread overview]
Message-ID: <51d29586$0$6567$9b4e6d93@newsspool4.arcor-online.net> (raw)
In-Reply-To: <40bf5a31-b09a-4106-a57a-7ac3dd5f951e@googlegroups.com>

On 01.07.13 13:11, Maurizio Tomasi wrote:
> Hi Dmitry,

>> Why don't you simply pass the array down to the C subprogram? You can do
>> something like:

>
> But what if A'Length is so large that the array does not fit into the stack?

Avoid pointers on the Ada side and you need not worry about
the stack. This is true insofar as Ada language definition
says that Ada arrays will be passed as pointers to the C world,
automatically. (See Interfacing to C)

Indeed, just do what is natural on both sides:
You can pass C-array variables (pointers) on the C side and
expect Ada to handle plain Ada-array variables. No pointers
needed. In fact, they complicate things due to doubled
indirections.

The following seems to work on my system.
The Ada side "imports" data and exports its subprograms.


#include <stdlib.h>
#include <stdio.h>

double call_ada (size_t n)
{
   extern void ada_side_takes_vector (double*, size_t);

   double *thing = malloc(n * sizeof(double));
   for (int k = 0; k < (int)n; ++k) {
     thing[k] = k;
   }
   ada_side_takes_vector(thing, n);
   return thing[n/2];
}

int main()
{
   extern void adainit(void);
   extern void adafinal(void);
   double result;
#define M ((2<<20)/sizeof(double))

   adainit();
   result = call_ada(500 * M);
   adafinal();
   printf("result is %f\n", result);
   return 0;
}

with Interfaces.C; use Interfaces;

package Bigimport is
    
    pragma Pure (Bigimport);
    
    subtype Dbl is C.Double;
    subtype Zint is C.ptrdiff_t range 0 .. C.ptrdiff_t'Last;
    
    type Lots_Of_Numbers is array (Zint) of Dbl;
    pragma Convention (C, Lots_Of_Numbers);
    
    procedure Takes_Vector
      (V : in out Lots_Of_Numbers;
       N : C.size_t);
    pragma Export (C, Takes_Vector, "ada_side_takes_vector");
    
end Bigimport;

package body Bigimport is
    
    procedure Takes_Vector
      (V : in out Lots_Of_Numbers; N : C.size_t)
    is
       use type Dbl, C.size_t;
    begin
       for K in Zint range 0 .. Zint(N-1) loop
          V(K) := V(K) / 2.0;
       end loop;
    end Takes_Vector;
    
end Bigimport;



  parent reply	other threads:[~2013-07-02  8:55 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-01  9:02 Thick bindings to a C library and gnattest: suggestions? ziotom78
2013-07-01  9:45 ` Dmitry A. Kazakov
2013-07-01 11:11   ` Maurizio Tomasi
2013-07-01 11:41     ` Simon Wright
2013-07-01 12:00       ` Maurizio Tomasi
2013-07-01 12:42         ` Dmitry A. Kazakov
2013-07-01 19:07           ` Simon Wright
2013-07-01 12:32     ` Dmitry A. Kazakov
2013-07-01 12:41       ` Maurizio Tomasi
2013-07-01 12:47       ` Simon Wright
2013-07-02  8:55     ` Georg Bauhaus [this message]
2013-07-02  8:33   ` Maurizio Tomasi
2013-07-02  8:58     ` Dmitry A. Kazakov
2013-07-02 16:58     ` Robert A Duff
2013-07-02 17:00     ` Jeffrey Carter
2013-07-01 17:16 ` Jeffrey Carter
2013-07-02  4:24   ` Randy Brukardt
2013-07-02  4:37     ` Shark8
2013-07-02  5:04     ` tmoran
2013-07-02 22:27       ` Randy Brukardt
2013-07-03 12:02   ` Jacob Sparre Andersen
2013-07-02  3:16 ` Jerry
2013-07-02  4:02   ` Shark8
replies disabled

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