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=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,b16d5240727960c4 X-Google-Attributes: gid103376,public Path: controlnews3.google.com!news1.google.com!newshub.sdsu.edu!newsfeed00.sul.t-online.de!t-online.de!newsfeed.wirehub.nl!news2.euro.net!62.253.162.219.MISMATCH!newsrout1.ntli.net!news-in.ntli.net!newspeer1-win.server.ntli.net!newsfe1-win.POSTED!53ab2750!not-for-mail From: "Dr. Adrian Wrigley" Subject: Re: C bindings, Interfaces.C.Pointers etc. User-Agent: Pan/0.14.2 (This is not a psychotic episode. It's a cleansing moment of clarity.) Message-ID: Newsgroups: comp.lang.ada References: <4934218.sMSg6xXRUe@linux1.krischik.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit Date: Thu, 13 May 2004 16:56:17 +0100 NNTP-Posting-Host: 81.100.88.147 X-Complaints-To: http://www.ntlworld.com/netreport X-Trace: newsfe1-win 1084463799 81.100.88.147 (Thu, 13 May 2004 15:56:39 GMT) NNTP-Posting-Date: Thu, 13 May 2004 15:56:39 GMT Organization: ntl Cablemodem News Service Xref: controlnews3.google.com comp.lang.ada:547 Date: 2004-05-13T16:56:17+01:00 List-Id: Thanks Martin for this suggestion. I have given (an approximation of) my code below. It doesn't use the I.C.Pointers package, and allows Ada programs to access elements of the arrays using standard array notation. The main problem is that the bound Ada uses are over-sized, and simple use of 'range and 'last will fall off the ends. I have used a generic package to create the appropriate types needed, and wrap the "malloc" and "free". This way, the C library can intermix allocations and deallocations with those of the Ada code. I put in the "aliased" - something I often forget until the compiler complains at me! Overall this solution meets my needs very well, and if I accidentally use the invalid array (upper) bound, the program crashes very rapidly (like it would have done in C with a similar bug!). I'm a little surprised that I.C.Pointers doesn't seem to provide a convenient and efficient solution to this problem - using C pointers directly in array access. The next problem I am thinking about with this project is how to abort a call into the C/C++ library safely. Sometimes the library takes *much* too long to compute a result. (If the parameters are unsuitable, it can take hours vs seconds with good parameters). If the thread executing the library call is aborted, memory will hemmorage from the application. This problem will probably need a hacked version of the (Open Source) library. I'm not sure how to communicate with the call as it executes telling it to clean up and exit immediately. Shared memory flags? Signals? Thanks for the input on these problems! -- Adrian generic type Element_T is private; IndexBase : Integer := 0; package CArrayUtils is type ElementArray_T is array (0 .. Interfaces.C.Size_T'Last) of aliased Element_T; pragma Convention (C, ElementArray_T); type ElementArray_A is access ElementArray_T; pragma Convention (C, ElementArray_A); function CAlloc (N : Integer) return ElementArray_A; procedure CFree (X : in out ElementArray_A); end CArrayUtils; package body CArrayUtils is function CAlloc (N : Integer) return ElementArray_A is function Malloc (A : Interfaces.C.Size_T) return ElementArray_A; pragma Import (C, Malloc, "malloc"); begin -- Is the size in bytes calculated correctly??? Probably not! return Malloc (Interfaces.C.Size_T (N * Element_T'Size / 8 + 1)); end CAlloc; procedure CFree (X : in out ElementArray_A) is procedure Free (X : ElementArray_A); pragma Import (C, Free, "free"); begin Free (X); X := null; end CFree; end CArrayUtils; with Interfaces.C; package Blob is type Node_T is record Index : Interfaces.C.Int; Value : Interfaces.C.Double; end record; pragma Convention (C, Node_T); package NodeArray_P is new CArrayUtils (Element_T => Node_T); subtype NodeArray_A is NodeArray_P.ElementArray_A; package NodeArrayArray_P is new CArrayUtils (Element_T => NodeArray_A); subtype NodeArrayArray_A is NodeArrayArray_P.ElementArray_A; package DoubleArray_P is new CArrayUtils (Element_T => Interfaces.C.Double); subtype DoubleArray_A is DoubleArray_P.ElementArray_A; type SVMProblem_T is record L : Interfaces.C.Int; Y : DoubleArray_A; -- Pointer to array of double X : NodeArrayArray_A; -- (pointer to array of (pointer to array of SVMNode)) end record; pragma Convention (C, Problem_T); end Blob;