Re: How to pass two dimensional arrays to C
- From: "Jerry" <lanceboyle@xxxxxxxxx>
- Date: 4 Aug 2006 18:03:21 -0700
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;
.
- References:
- How to pass two dimensional arrays to C
- From: Jerry
- How to pass two dimensional arrays to C
- Prev by Date: Re: The Holy Shroud
- Next by Date: Re: Qt4Ada: Qt for Ada
- Previous by thread: Re: How to pass two dimensional arrays to C
- Next by thread: web page moved
- Index(es):
Relevant Pages
|