comp.lang.ada
 help / color / mirror / Atom feed
From: Victor Porton <porton@narod.ru>
Subject: Re: Convert between C "void*" pointer and an access
Date: Thu, 12 Oct 2017 01:58:29 +0300
Date: 2017-10-12T01:58:29+03:00	[thread overview]
Message-ID: <orm7mj$163$1@gioia.aioe.org> (raw)
In-Reply-To: orm3qe$1r0c$1@gioia.aioe.org

Victor Porton wrote:

> What is the right way to convert between C "void*" pointer and an access
> to a tagged or class-wide type?
> 
> Ada.Unchecked_Conversion seems to be what I need, but the access type may
> be "fat" and thus have another format than void*.
> 
> I caught myself doing such unchecked conversions, but now I feel I did an
> error.
> 
> For example, let
> 
> type X_Type is abstract tagged null record;
> 
> How to store X_Type'Class pointer in "void*" and convert them back and
> forth?

It seems I've found a right solution of my problem. (Check if Ada RM
warrants that it works with every compiler!)

Well, why it is not a standard package?! Why I need to invent something
"smart" every time I need to code?

with System.Address_To_Access_Conversions;
with Interfaces.C.Strings; use Interfaces.C.Strings;

-- C11, 6.2.5, 28 (draft N1548):
-- A pointer to void shall have the same representation and alignment requirements as a pointer to a character type.
-- So we can use chars_ptr to mean void pointer in C.

generic
    type Object(<>) is limited private;
package Convert_Void is

   package Address_Conversions is new System.Address_To_Access_Conversions(Object);

   subtype Object_Pointer is Address_Conversions.Object_Pointer;

   function To_Access (Void_Pointer: chars_ptr) return Object_Pointer;

   function To_C_Pointer (Pointer: Object_Pointer) return chars_ptr;

end Convert_Void;


with Ada.Unchecked_Conversion;

package body Convert_Void is

   type My_Char_Pointer is access all char with Convention=>C;

   function From_My_Char_Pointer is new Ada.Unchecked_Conversion(My_Char_Pointer, chars_ptr);
   function From_Chars_Ptr is new Ada.Unchecked_Conversion(chars_ptr, My_Char_Pointer);

   package Char_Address_Conversions is new System.Address_To_Access_Conversions(char);

   function To_Access (Void_Pointer: chars_ptr) return Object_Pointer is
   begin
      return Address_Conversions.To_Pointer(From_Chars_Ptr(Void_Pointer)'Address);
   end;

   function To_C_Pointer (Pointer: Object_Pointer) return chars_ptr is
      A: constant System.Address := Address_Conversions.To_Address(Pointer);
      P: constant My_Char_Pointer :=
        My_Char_Pointer(Char_Address_Conversions.To_Pointer(A));
   begin
      return From_My_Char_Pointer(P);
   end;

end Convert_Void;

-- 
Victor Porton - http://portonvictor.org

  parent reply	other threads:[~2017-10-11 22:58 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-11 21:52 Convert between C "void*" pointer and an access Victor Porton
2017-10-11 22:32 ` Randy Brukardt
2017-10-11 23:03   ` Victor Porton
2017-10-12  7:57     ` Dmitry A. Kazakov
2017-10-12  8:05     ` Simon Wright
2017-10-29 14:50   ` David Thompson
2017-10-11 22:58 ` Victor Porton [this message]
2017-10-11 23:12   ` Victor Porton
2017-10-12  1:01     ` Victor Porton
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox