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 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!aioe.org!.POSTED!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: Convert between C "void*" pointer and an access Date: Thu, 12 Oct 2017 09:57:28 +0200 Organization: Aioe.org NNTP Server Message-ID: References: NNTP-Posting-Host: lKHBldubgAWx1EqbQpQ5LQ.user.gioia.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Complaints-To: abuse@aioe.org User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0 Content-Language: en-US X-Notice: Filtered by postfilter v. 0.8.2 Xref: news.eternal-september.org comp.lang.ada:48438 Date: 2017-10-12T09:57:28+02:00 List-Id: On 12/10/2017 01:03, Victor Porton wrote: > Randy Brukardt wrote: > >> "Victor Porton" wrote in message >> news:orm3qe$1r0c$1@gioia.aioe.org... >>> What is the right way to convert between C "void*" pointer and an access >>> to >>> a tagged or class-wide type? >> >> I doubt that there is a *right* way, there just are several possibilities. >> >>> Ada.Unchecked_Conversion seems to be what I need, but the access type may >>> be >>> "fat" and thus have another format than void*. >> >> Right, but not very likely. I'd expect this to work in most cases. >> >> But our solution in the Claw libraries was simply to use the appropriate >> C-convention access type in the interface definitions and avoid making any >> conversions at all. I believe that on the C side, void* and >> * have to use the same representation, so C convention >> should work properly for any pointer type. >> >> That is, if the C interface contains a void* parameter, we just used an >> appropriate C convention access type in its place in the Ada parameter >> definition. (Using overloading if we needed multiple such pointers - but >> that was very rare.) There's no counterpart to void* in Ada anyway, so one >> has to do something like that in the interfacing definitions. > > "- What is your solution for Windows printing problems? - Do not print." > > I NEED to convert between access to tagged records (and access to class-wide > types) and C void* pointers. > > I need this because it is C's way to pass objects by using void* and I need > to pass Ada objects to C functions (not just C objects). What Randy says is that in many cases you can pass an Ada access type where void * is expected: type T is tagged whatever ...; -- -- void c_foo (void * userdata); -- type T_Ptr is access all T['Class]; pragma Convention (C, T_Ptr); procedure Set_Callback (..., User_Data : T_Ptr); pragma Import (C, Set_Callback, "..."); This is the most safe and clean way to pass pointers to Ada objects through C library, assuming that C does not touch the object. In other cases you can simply declare it System.Address and use Access_To_Address conversion or the Address pragma/aspect or fake pool allocator new. Whatever you like. System.Address is frowned at because it not guaranteed to work everywhere, but chances are high that if that does not work nothing else would either. So I would not worry too much about it. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de