Re: How to pass two dimensional arrays to C



I want to close off this thread for the record.

Many thanks to everyone who helped me.

I have a working solution, pasted in sketch form below.

My only complaint with this solution is that I wanted to keep the thin
bindings, PlplotThin.ads, available and as a complete binding to anyone
who prefers it, if for no other reason than it is notationally closer
to the documentation (and _was_ essentially complete while the thick
binding will be finished only as my spare time permits). With this
solution, any PLplot subprogram which takes a two-dimensional array is
no longer accessible from the thin binding.

Maybe someday I'll learn enough Ada to find a way around this, but for
now, this works:


=============== my_common.ads
package My_Common is
type Long_Float_Array_1D is array (Integer range <>) of aliased
Long_Float;
type Long_Float_Array_2D is array (Integer range <>, integer range
<>) of aliased Long_Float;
end My_Common;



=============== plplotthin.ads
with
My_Common;

package PLplotThin is
subtype PLINT is Integer;
subtype PLFLT is Long_Float;
subtype PL_Float_Array is My_Common.Long_Float_Array_1D;
subtype PL_Float_Array_2D is My_Common.Long_Float_Array_2D;

-- procedure plmesh is not defined in this package, but
-- but in the thick binding PLplot wrapped in Mesh_3D.
-- The same applies for the various other 3D plotters such
-- as plmeshc, plot3d, plot3dc, and others which take a
-- two-dimensional array as a parameter.
-- These routines are unavailable from this thin binding.
end PLplotThin;


=============== plplot.adb
with
PLplotThin,
My_Common,
Interfaces.C.Pointers,
Interfaces.C;
use
PLplotThin,
My_Common,
Interfaces.C;

package body PLplot is

procedure Mesh_3D
(x, y : Long_Float_Array_1D; -- surface definition points
z : in out Long_Float_Array_2D; -- height of surface at
definition points
Options : Integer) is

package PL_Float_Pointers_Local is new Interfaces.C.Pointers
(Index => Integer,
Element => Long_Float,
Element_Array => Long_Float_Array_1D,
Default_Terminator => 0.0);
use type PL_Float_Pointers_Local.Pointer; -- as in RM B.3.2
type PL_Float_Pointer_Array_Local is array (Integer range <>)
of PL_Float_Pointers_Local.Pointer; -- array of pointers to Long_Floats
which represent the first element of each row of z in C-land

Index_Of_First_Column : Integer := z'First(2);
z_As_Pointers : PL_Float_Pointer_Array_Local (z'range(1));

procedure
plmesh_local(x : PL_Float_Array; y : PL_Float_Array; z :
PL_Float_Pointer_Array_Local; nx : Integer; ny : Integer; opt :
Integer);
pragma Import(C, plmesh_local, "c_plmesh");

begin
for Index in z'range(1) loop
z_As_Pointers(Index) := z(Index,
Index_Of_First_Column)'access;
end loop;
plmesh_local(x, y, z_As_Pointers, x'Length, y'Length, Options);
-- pass z_As_Pointers here rather than z
end Mesh_3D;

end PLplot;


=============== Testing_Thick_Binding.adb
with
PlplotThin,
PLplot,
My_Common;
use
PlplotThin,
PLplot,
My_Common;

package body Testing_Thick_Binding is
procedure Main_Testing_Thick_Binding is
z : aliased Long_Float_Array_2D (1..xpts, 1..ypts);
pragma Convention(C, z); -- for compatibility with non-GNAT
x : Long_Float_Array_1D (1..xpts);
pragma Convention(C, x); -- for compatibility with non-GNAT
y : Long_Float_Array_1D (1..ypts);
pragma Convention(C, y); -- for compatibility with non-GNAT
begin -- Main_Testing_Thick_Binding
-- ...
-- Calculate x, y, z.
-- etc.
-- ...
Mesh_3D(x, y, z, Options); -- call plmesh wrapper
-- Clean up.
end Main_Testing_Thick_Binding;
end Testing_Thick_Binding;

.



Relevant Pages

  • Re: Isnt this in favour of Ada??
    ... abstraction that could be either hardware triggered, OS triggered or software triggered so that the protected procedure could do what it is currently doing to connect to an interrupt, but you could hide the triggering mechanism under a package body somewhere. ... What I'm looking for is a mechanism that lets you hide the SOURCE of the interrupt in a package BODY so that the embedded executive developer and the workstation simulation developer can both work from a common specification and all we have to do to get off the target and on to the simulation is substitute one package body. ... Also in the package would be a generic package with two procedures for binding and unbinding the interrupt to a task or protected object entry. ...
    (comp.lang.ada)
  • Re: Standard Ada Preprocessor
    ... you can dumb it down to a "standard" (or omit non-universal ... > control package leaves me with 4 different package bodies to deal with, ... Ah, but you cannot assume that the binding for PDcurses, ... > This thread is about a standard preprocessor. ...
    (comp.lang.ada)
  • Re: in-package function vs macro
    ... Binding *PACKAGE* (be it directly, or using the IN-PACKAGE macro) ... inside a form cannot have any influence on the form itself, ...
    (comp.lang.lisp)
  • Re: Macro/package problem
    ... > the body with this new binding, ... > different package than the &body code? ... macro expansion time. ...
    (comp.lang.lisp)