From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 X-Received: by 10.157.10.87 with SMTP id 81mr5312551otg.9.1460541705072; Wed, 13 Apr 2016 03:01:45 -0700 (PDT) X-Received: by 10.157.11.183 with SMTP id 52mr89150oth.17.1460541705025; Wed, 13 Apr 2016 03:01:45 -0700 (PDT) Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!mx02.eternal-september.org!feeder.eternal-september.org!news.glorb.com!nt3no12360463igb.0!news-out.google.com!u9ni74igk.0!nntp.google.com!nt3no12360458igb.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Wed, 13 Apr 2016 03:01:44 -0700 (PDT) Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=97.117.194.246; posting-account=x5rpZwoAAABMN2XPwcebPWPkebpwQNJG NNTP-Posting-Host: 97.117.194.246 User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: Subject: Help with PLplot bindings: How to pass a record of function pointers to a procedure From: Jerry Injection-Date: Wed, 13 Apr 2016 10:01:45 +0000 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Xref: news.eternal-september.org comp.lang.ada:30090 Date: 2016-04-13T03:01:44-07:00 List-Id: Sorry for the long messy post. I'm trying to update the Ada bindings for the PLplot plotter software (http= ://plplot.sourceforge.net/) and am stumped. Background: The C version has added support for the 3D plotters for z =3D f= (x, y) data where z can be stored in various ways--the usual pointer to an = array of pointers, a struct with the same thing but adding the bounds as ad= ditional struct fields, or as a one-dimensional row-major or column-major a= rrays. One function call to the C 3D surface plotter works for all kinds of= z storage. The C code has these declarations (I have edited out additional fields for = simplicity; PLFLT maps to Ada Long_Float and PLINT maps to Integer, PLPoint= er is a C pointer to the z data, here called p): typedef struct { PLFLT ( *get )( PLPointer p, PLINT ix, PLINT iy ); PLFLT ( *set )( PLPointer p, PLINT ix, PLINT iy, PLFLT z ); } plf2ops_t; typedef plf2ops_t * PLF2OPS; I understand the struct to have fields that are pointers to get and set fun= ctions. Then there is, for the case where z is stored as a pointer to an array of p= ointers (these declarations etc. are in multiple files), static PLFLT plf2ops_c_get( PLPointer p, PLINT ix, PLINT iy ) { return ( (PLFLT **) p )[ix][iy]; } static PLFLT plf2ops_c_set( PLPointer p, PLINT ix, PLINT iy, PLFLT z ) { return ( ( (PLFLT **) p )[ix][iy] =3D z ); } (These "get" and "set" functions are later offered in forms suitable for th= e other forms of z storage, e.g., struct-with-bounds, row-major, and column= -major.) Then there is this, for the pointer-to-pointers form of data manipulation d= escribed above: static plf2ops_t s_plf2ops_c =3D { plf2ops_c_get, plf2ops_c_set, }; which I understand to be a variable of the struct declared with the fields = filled in with the appropriate functions. Then: PLF2OPS plf2ops_c() { return &s_plf2ops_c; } This is then used in the 3D surface plotter call as such: plfsurf3d(x, y, plf2ops_c(), (PLPointer) z, XPTS, YPTS); where x and y are arrays (pointers again) where z is evaluated, mathematica= lly, z =3D f(x, y), and XPTS and YPTS are the sizes of x (XPTS), y (YPTS), = z (YPTS by XPTS). I have tried to emulate this in Ada in part as follows, but I'm doing somet= hing seriously wrong. type Function_To_Manipulate_Matrix_A_Type is access function (p : Real_Matrix; ix, iy : Integer) return Long_Float; type Function_To_Manipulate_Matrix_B_Type is access function (p : in out Real_Matrix; ix, iy : Integer; z : Long_Flo= at) return Long_Float; (Don't worry about my use of Real_Matrix here--I have a function to convert= it to a pointer to an array of pointers to make C happy.) type PLf2ops_Type is record Get : Function_To_Manipulate_Matrix_A_Type; Set : Function_To_Manipulate_Matrix_B_Type; end record; function plf2ops_c_get(p : Real_Matrix; ix, iy : Integer) return Long_Float= ; pragma Import(C, plf2ops_c_get, "plf2ops_c_get"); function plf2ops_c_set(p : Real_Matrix; ix, iy : Integer; z : Long_Float) r= eturn Long_Float; pragma Import(C, plf2ops_c_set, "plf2ops_c_set"); s_plf2ops_c : PLf2ops_Type :=3D (Get =3D> plf2ops_c_get(p : Real_Matrix; ix, iy : Integer), Set =3D> plf2ops_c_set(p : Real_Matrix; ix, iy : Integer; z : Long_Floa= t)); but this doesn't compile, nor do some variations that I have tried. How do = I get this done so that I can pass a record of function pointers to plfsurf= 3d that is compatible with how C does it (and actually compiles in Ada)? Re= member that the functions plf2ops_c_get and plf2ops_c_set have differently-= named and -implemented counterparts for other z-storage methods, e.g. plf2ops_grid_row_major_get( PLPointer p, PLINT ix, PLINT iy ) { PLfGrid2 *g =3D (PLfGrid2 *) p; return ( (PLFLT *) g->f )[ix * g->ny + iy]; } then e.g. plfsurf3d(x, y, plf2ops_grid_row_major(), ( PLPointer ) & grid_row_major, X= PTS, YPTS); Jerry