* System.Address to Access to function/procedure conversion
@ 2013-07-28 15:27 Tarek Ghaleb
2013-07-28 16:14 ` Dmitry A. Kazakov
` (2 more replies)
0 siblings, 3 replies; 15+ messages in thread
From: Tarek Ghaleb @ 2013-07-28 15:27 UTC (permalink / raw)
Hi Everyone,
This is my first post to comp.lang.ada and it is so embarrassingly
trivial. Given an Address of a function/procedure, how can you call it
or convert the address to an access?
I first thought of System.Address_To_Access_Conversions, but then it
doesn't seem to work for a function/procedure.
The way I finally did it was to wrap an access to the function in a
record and then pass the Address of the record, but there must be a
simpler way.
As for why not just pass an Access to the function directly, the
Address is actually passed to a C function which later passes it back
to Ada.
Tarek.
--
For fools rush in where angels fear to tread. -- Alexander Pope
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: System.Address to Access to function/procedure conversion
2013-07-28 15:27 System.Address to Access to function/procedure conversion Tarek Ghaleb
@ 2013-07-28 16:14 ` Dmitry A. Kazakov
2013-07-28 19:05 ` Tarek Ghaleb
2013-07-28 17:19 ` Jeffrey Carter
2013-07-28 21:31 ` Maciej Sobczak
2 siblings, 1 reply; 15+ messages in thread
From: Dmitry A. Kazakov @ 2013-07-28 16:14 UTC (permalink / raw)
On Sun, 28 Jul 2013 15:27:48 +0000 (UTC), Tarek Ghaleb wrote:
> As for why not just pass an Access to the function directly, the
> Address is actually passed to a C function which later passes it back
> to Ada.
If you pass anything to C you should better keep it under C convention,
even if you are certain that C does not touch it. You should pass an
access-to-procedure/function to C and get it back. The access type will
have pragma Convention (C, ... set. You don't need address here. E.g.
type Func is access procedure (...);
pragma Convention (C, Func);
procedure C_Stuff (...; Call_Back_Ptr : Func; ...);
pragma Import (C, C_Stuff, "fancy_c_library_entry");
The rationale is that, maybe unlikely still the access type might have a
different size than address and/or C pointer. When you use pragma
Convention (or the corresponding aspect if in Ada 2012) it is guaranteed to
work.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: System.Address to Access to function/procedure conversion
2013-07-28 15:27 System.Address to Access to function/procedure conversion Tarek Ghaleb
2013-07-28 16:14 ` Dmitry A. Kazakov
@ 2013-07-28 17:19 ` Jeffrey Carter
2013-07-28 19:05 ` Tarek Ghaleb
2013-07-28 21:31 ` Maciej Sobczak
2 siblings, 1 reply; 15+ messages in thread
From: Jeffrey Carter @ 2013-07-28 17:19 UTC (permalink / raw)
On 07/28/2013 08:27 AM, Tarek Ghaleb wrote:
>
> As for why not just pass an Access to the function directly, the
> Address is actually passed to a C function which later passes it back
> to Ada.
If you want any semblance of portability, then you should never pass an Address
to C. You should only pass a C-convention access type. The value must be stored
as a pointer on the C side, and there is no guarantee that Ada's Address has any
relationship to a C pointer. A C-convention access type, on the other hand, is
guaranteed to make sense as a C pointer.
--
Jeff Carter
"Oh Lord, bless this thy hand grenade, that with it thou
mayst blow thine enemies to tiny bits, in thy mercy."
Monty Python and the Holy Grail
24
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: System.Address to Access to function/procedure conversion
2013-07-28 16:14 ` Dmitry A. Kazakov
@ 2013-07-28 19:05 ` Tarek Ghaleb
2013-07-28 19:23 ` Simon Wright
` (2 more replies)
0 siblings, 3 replies; 15+ messages in thread
From: Tarek Ghaleb @ 2013-07-28 19:05 UTC (permalink / raw)
On 2013-07-28, Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> If you pass anything to C you should better keep it under C convention,
> even if you are certain that C does not touch it. You should pass an
> access-to-procedure/function to C and get it back. The access type will
> have pragma Convention (C, ... set. You don't need address here. E.g.
I agree completely. Using C convention is the way to do it. But is it
*possible* to call a function using its address? (even if not a such a
great idea)
But let me explain how this question came about:
I've been experimenting with writing a thick binding for FLTK for a
couple of days now, just exploring the idea (which deserves a thread
by itself, since it would be interesting to get some
feedback). Anyway, one thing I started working on was callbacks, If I
use C convention the user of the binding will also have to declare his
procedure using C convention. For example (simplified)
procedure Cb_Button;
pragma Convention (C, Cb_Button); -- This is required I guess
and then later register the callback with
Btn.Callback(Cb_Button'Access);
But if I remove
pragma Conversion (C, Cb_Button);
I get
...: subprogram "Cb_Button" has wrong convention
...: does not match convention of access type
But I don't want the user to worry about using pragma Convention for
every defined callback procedure or think in terms of interfacing with
C (or in FLTK's case C++). Ideally, Callback() is not the actual
imported callback() but it takes Ada friendly parameters and does any
type conversions needed then calls the imported callback() function. I
thought maybe it works like above but without the convention line and
then Callback() would send the Address instead of the Access to the
actual callback(). But maybe there is a better way to do it.
There are other issues of course, for example: callbacks do take
parameters and some are void* but that would complicate my question
for the time being.
Tarek.
--
For fools rush in where angels fear to tread. -- Alexander Pope
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: System.Address to Access to function/procedure conversion
2013-07-28 17:19 ` Jeffrey Carter
@ 2013-07-28 19:05 ` Tarek Ghaleb
2013-07-28 20:04 ` Jeffrey Carter
0 siblings, 1 reply; 15+ messages in thread
From: Tarek Ghaleb @ 2013-07-28 19:05 UTC (permalink / raw)
On 2013-07-28, Jeffrey Carter <spam.jrcarter.not@spam.not.acm.org> wrote:
> If you want any semblance of portability, then you should never pass
> an Address to C. You should only pass a C-convention access type.
I agree, it is a much cleaner and portable way to do it.
> ... there is no guarantee that Ada's Address has any relationship to
> a C pointer.
Interesting, I thought System.Address was equivalent to a C pointer,
and I've seen it used that way in many snippets of code, etc. For
things like void*, if not represented as System.Address, how would it
be represented then?
Tarek.
--
For fools rush in where angels fear to tread. -- Alexander Pope
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: System.Address to Access to function/procedure conversion
2013-07-28 19:05 ` Tarek Ghaleb
@ 2013-07-28 19:23 ` Simon Wright
2013-07-28 22:03 ` Tarek Ghaleb
2013-07-28 20:03 ` Dmitry A. Kazakov
2013-07-28 21:13 ` Shark8
2 siblings, 1 reply; 15+ messages in thread
From: Simon Wright @ 2013-07-28 19:23 UTC (permalink / raw)
Tarek Ghaleb <invalid@invalid.org> writes:
> Ideally, Callback() is not the actual imported callback() but it takes
> Ada friendly parameters and does any type conversions needed then
> calls the imported callback() function.
I find this confusing because I'm used to thinking of the procedure-to-
be-called-back as the 'callback', and what you're talking about here is
the registration interface. But if that's FLTK's nomenclature ...
Especially if the called-back procedure takes parameters, you're going
to have to do a conversion on the way back as well! I think you might be
able to do something with a generic, but .. you can't make a generic
formal type definition that declares an "access to procedure with this
parameter profile" type.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: System.Address to Access to function/procedure conversion
2013-07-28 19:05 ` Tarek Ghaleb
2013-07-28 19:23 ` Simon Wright
@ 2013-07-28 20:03 ` Dmitry A. Kazakov
2013-07-28 21:13 ` Shark8
2 siblings, 0 replies; 15+ messages in thread
From: Dmitry A. Kazakov @ 2013-07-28 20:03 UTC (permalink / raw)
On Sun, 28 Jul 2013 19:05:44 +0000 (UTC), Tarek Ghaleb wrote:
> On 2013-07-28, Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
>> If you pass anything to C you should better keep it under C convention,
>> even if you are certain that C does not touch it. You should pass an
>> access-to-procedure/function to C and get it back. The access type will
>> have pragma Convention (C, ... set. You don't need address here. E.g.
>
> I agree completely. Using C convention is the way to do it. But is it
> *possible* to call a function using its address? (even if not a such a
> great idea)
>
> But let me explain how this question came about:
>
> I've been experimenting with writing a thick binding for FLTK for a
> couple of days now, just exploring the idea (which deserves a thread
> by itself, since it would be interesting to get some
> feedback). Anyway, one thing I started working on was callbacks, If I
> use C convention the user of the binding will also have to declare his
> procedure using C convention. For example (simplified)
>
> procedure Cb_Button;
> pragma Convention (C, Cb_Button); -- This is required I guess
>
> and then later register the callback with
>
> Btn.Callback(Cb_Button'Access);
>
> But if I remove
>
> pragma Conversion (C, Cb_Button);
>
> I get
>
> ...: subprogram "Cb_Button" has wrong convention
> ...: does not match convention of access type
>
> But I don't want the user to worry about using pragma Convention for
> every defined callback procedure or think in terms of interfacing with
> C (or in FLTK's case C++). Ideally, Callback() is not the actual
> imported callback() but it takes Ada friendly parameters and does any
> type conversions needed then calls the imported callback() function. I
> thought maybe it works like above but without the convention line and
> then Callback() would send the Address instead of the Access to the
> actual callback(). But maybe there is a better way to do it.
Usually C bindings pass an internal procedure of C convention. The user
provided callback is called from there. From my POV it is too low level for
good bindings. I prefer primitive operations of a tagged type instead of
using a raw subprogram. E.g. an interface with the operation Clicked passed
to button's On_Click.
type Button_Interface is limited interface;
procedure Clicked (Handler : in out Button_Interface;
Issuer : Widget'Class) is abstract;
type Button is ...
procedure On_Click (Widget : in out Button;
Handler : not null access Button_Interface'Class); -- [*]
Normally C library call takes an additional parameter void* passed as a
"User_Data" argument etc. Almost all C libraries provide such user data
arguments. This is a way to marshal parameters to the C callback from where
you call an Ada subprogram or dispatch.
Depending on what is the recipient of the callback you choose the strategy
of marshaling data through void*. A typical way for a widget library is
that when you connect to a signal emitted by a widget, a reference counted
object is allocated by the C library. The library deletes the object when
the signal gets disconnected or when the widget is destroyed. This object
is directly or indirectly pointed by the User_Data argument. There are
various issues when which object gets deallocated, which is not simple
stuff, but almost always necessary because user parameters never fit into
single void* argument.
When no user data argument is supported, you would use so-called
"trampolines", which is of course quite nasty stuff.
-------------
* You would like to wrap Button_Interface into a smart pointer object and
use the latter in On_Click.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: System.Address to Access to function/procedure conversion
2013-07-28 19:05 ` Tarek Ghaleb
@ 2013-07-28 20:04 ` Jeffrey Carter
0 siblings, 0 replies; 15+ messages in thread
From: Jeffrey Carter @ 2013-07-28 20:04 UTC (permalink / raw)
On 07/28/2013 12:05 PM, Tarek Ghaleb wrote:
>
> Interesting, I thought System.Address was equivalent to a C pointer,
> and I've seen it used that way in many snippets of code, etc. For
> things like void*, if not represented as System.Address, how would it
> be represented then?
Such code is compiler-dependent. GNAT usually (always?) maintains a
correspondence between hardware address, System.Address, access types, and C
pointers, but I've certainly used compilers where that wasn't true. I recall one
system written originally with GNAT that was ported to Rational (same platform).
The code used Unchecked_Conversion between access types and System.Address,
which failed miserably on Rational, where the 2 were not the same. It had to be
revised to use System.Address_To_Access_Conversions, which was not a trivial
undertaking. Moral: it's usually cheaper to write portable code in the 1st place.
A void* passed between C and Ada is usually C's equivalent of a private type,
with all values coming from C and never dereferenced by Ada. For such cases, all
that we need to model in Ada is that what we have is a C pointer. The
implementation usually looks like
type Void is null record;
type Void_Ptr is access all Void;
pragma Convention (C, Void_Ptr);
Of course, there's no real need for type Void; Void_Ptr could be "access all
Integer" and it would work just as well. The advantage of using Void is that
anyone who dereferences a Void_Ptr gets something useless.
If Void_Ptr is declared publicly, it should obviously be [limited] private. And
usually there's a better name for it than Void_Ptr.
--
Jeff Carter
"Oh Lord, bless this thy hand grenade, that with it thou
mayst blow thine enemies to tiny bits, in thy mercy."
Monty Python and the Holy Grail
24
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: System.Address to Access to function/procedure conversion
2013-07-28 19:05 ` Tarek Ghaleb
2013-07-28 19:23 ` Simon Wright
2013-07-28 20:03 ` Dmitry A. Kazakov
@ 2013-07-28 21:13 ` Shark8
2013-07-28 22:54 ` Tarek Ghaleb
2 siblings, 1 reply; 15+ messages in thread
From: Shark8 @ 2013-07-28 21:13 UTC (permalink / raw)
On Sunday, July 28, 2013 1:05:44 PM UTC-6, Tarek Ghaleb wrote:
> On 2013-07-28, Dmitry A. Kazakov wrote:
>
> > If you pass anything to C you should better keep it under C convention,
> > even if you are certain that C does not touch it. You should pass an
> > access-to-procedure/function to C and get it back. The access type will
> > have pragma Convention (C, ... set. You don't need address here. E.g.
>
> I agree completely. Using C convention is the way to do it. But is it
> *possible* to call a function using its address? (even if not a such a
> great idea)
Yes. It's actually absurdly easy. Here's a sample of how to do it in Ada 2012, the same will work in earliet versions of Ada using Pargmas... all the way back to 83, IIUC.
-- Used a declare-block for expedience; I had a test-bed file open.
-- Be sure to WITH System.
ACTUAL_TEST:
declare
Procedure K with Convention => C;
Procedure K is
begin
Ada.Text_IO.Put_Line( "K was called" );
end K;
Procedure Execute( Addr : System.Address ) is
Procedure Stub with Import, Convention => C, Address => Addr;
Begin
Stub;
End Execute;
begin
Execute( K'Address );
end ACTUAL_TEST;
And there you are.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: System.Address to Access to function/procedure conversion
2013-07-28 15:27 System.Address to Access to function/procedure conversion Tarek Ghaleb
2013-07-28 16:14 ` Dmitry A. Kazakov
2013-07-28 17:19 ` Jeffrey Carter
@ 2013-07-28 21:31 ` Maciej Sobczak
2013-07-29 6:26 ` Tarek Ghaleb
2 siblings, 1 reply; 15+ messages in thread
From: Maciej Sobczak @ 2013-07-28 21:31 UTC (permalink / raw)
> Given an Address of a function/procedure, how can you call it
> or convert the address to an access?
This article can be helpful:
http://www.inspirel.com/articles/Polymorphic_Callbacks_Ada_Cpp.html
The article goes even further than what you describe, as it shows polymorphic (object-oriented) callbacks, so in your case the actual solution might be one or two details simpler. In any case, it uses System.Address and standard Ada conversions to do the work.
--
Maciej Sobczak * http://www.msobczak.com * http://www.inspirel.com
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: System.Address to Access to function/procedure conversion
2013-07-28 19:23 ` Simon Wright
@ 2013-07-28 22:03 ` Tarek Ghaleb
0 siblings, 0 replies; 15+ messages in thread
From: Tarek Ghaleb @ 2013-07-28 22:03 UTC (permalink / raw)
On 2013-07-28, Simon Wright <simon@pushface.org> wrote:
> Tarek Ghaleb <invalid@invalid.org> writes:
>
>> Ideally, Callback() is not the actual imported callback() but it takes
>> Ada friendly parameters and does any type conversions needed then
>> calls the imported callback() function.
>
> I find this confusing because I'm used to thinking of the procedure-to-
> be-called-back as the 'callback', and what you're talking about here is
> the registration interface. But if that's FLTK's nomenclature ...
Yes, this is the naming for FLTK, but I can change that I guess. I
probably should have used a different name here for clarity, Register()
perhaps or Register_Callback().
> Especially if the called-back procedure takes parameters, you're going
> to have to do a conversion on the way back as well!
Initially, I thought it was simple, but now it doesn't seem so easy
:-) I'd want to wrap the user callback, Button_Cb() for example, in
another procedure that fits the profile required by the imported
callback registration function and does that conversion and calling of
Button_Cb().
One idea of the Registration procedure, stripped down and not
considering parameters and parameter conversion (but saves the user
from having to use pragma Convention C) is
procedure Register_Callback (Proc : access procedure) is
procedure Cb_Wrapper;
pragma Convention (C, Cb_Wrapper);
procedure Cb_Wrapper is
begin
Proc.all;
end Cb_Wrapper;
begin
imported_callback_registration (Cb_Wrapper'Access);
end Register_Callback;
But this of course wouldn't work, since the Wrapper is allocated on
the stack and is deeper than access type.
> I think you might be able to do something with a generic, but .. you
> can't make a generic formal type definition that declares an "access
> to procedure with this parameter profile" type.
A generic used in which way? I'd like Register_Callback() to be
callable simply with an access to a procedure that fits a certain
profile with the caller not having to worry about details. The wrapper
could be a generic maybe. There are a couple of other ideas but
nothing promising so far.
Tarek.
--
The opposite of a correct statement is a false statement. But the opposite
of a profound truth may well be another profound truth. -- Niels Bohr
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: System.Address to Access to function/procedure conversion
2013-07-28 21:13 ` Shark8
@ 2013-07-28 22:54 ` Tarek Ghaleb
2013-07-29 3:27 ` Shark8
0 siblings, 1 reply; 15+ messages in thread
From: Tarek Ghaleb @ 2013-07-28 22:54 UTC (permalink / raw)
On 2013-07-28, Shark8 <onewingedshark@gmail.com> wrote:
>> I agree completely. Using C convention is the way to do it. But is it
>> *possible* to call a function using its address? (even if not a such a
>> great idea)
> Yes. It's actually absurdly easy. Here's a sample of how to do it in
> Ada 2012, the same will work in earliet versions of Ada using
> Pargmas... all the way back to 83, IIUC.
> ACTUAL_TEST:
> declare
>
> Procedure K with Convention => C;
> Procedure K is
> begin
> Ada.Text_IO.Put_Line( "K was called" );
> end K;
>
> Procedure Execute( Addr : System.Address ) is
> Procedure Stub with Import, Convention => C, Address => Addr;
> Begin
> Stub;
> End Execute;
>
> begin
> Execute( K'Address );
> end ACTUAL_TEST;
Great! I didn't know about the Address Aspect. I don't think it exists
in pragma form, though. At least I couldn't find it in the RM; but
thanks, that answers my question.
Tarek.
--
Aim for the moon. If you miss, you may hit a star. -- W. Clement Stone
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: System.Address to Access to function/procedure conversion
2013-07-28 22:54 ` Tarek Ghaleb
@ 2013-07-29 3:27 ` Shark8
2013-07-29 7:06 ` Tarek Ghaleb
0 siblings, 1 reply; 15+ messages in thread
From: Shark8 @ 2013-07-29 3:27 UTC (permalink / raw)
On Sunday, July 28, 2013 4:54:27 PM UTC-6, Tarek Ghaleb wrote:
> On 2013-07-28, Shark8 wrote:
>
> >> I agree completely. Using C convention is the way to do it. But is it
> >> *possible* to call a function using its address? (even if not a such a
> >> great idea)
>
> > Yes. It's actually absurdly easy. Here's a sample of how to do it in
> > Ada 2012, the same will work in earliet versions of Ada using
> > Pargmas... all the way back to 83, IIUC.
Oops; a little overzealous there.
You have to use attribute definition clauses, which IIRC came in Ada 95.
Below compiles and runs in GNAT using Ada83-mode:
-- Pragma Ada_2012;
Pragma Ada_83;
Pragma Assertion_Policy( Check );
With
Text_IO,
System;
Procedure Test is
Begin
Text_IO.Put_Line("Starting Test:");
ACTUAL_TEST:
declare
-- Note: Pragma CONVENTION is non-standard.
Procedure K;
Pragma Convention( C, K );
Procedure K is
begin
Text_IO.Put_Line( "K was called" );
end K;
Procedure Execute( Addr : System.Address ) is
-- Note: Pragma IMPORT is non-standard.
Procedure Stub;
Pragma Import( C, Stub );
-- Note: The Ada 83 LRM, 13.5 (Address Clauses) gives the following:
-- for CONTROL use at 16#0020#; -- assuming that SYSTEM.ADDRESS is an integer
-- with the following warning:
-- Address clauses should not be used to achieve overlays of
-- objects or overlays of program units. Nor should a given
-- interrupt be linked to more than one entry. Any program using
-- address clauses to achieve such effects is erroneous.
--
-- In Ada 95 we get propper Attribute Definition Clauses and so
-- we would use the following:
-- For Stub'Address Use Addr;
For Stub use at Addr;
Use Text_IO;
Begin
Put_Line( "Executing:" );
Put( ASCII.HT );
Stub;
End Execute;
begin
Execute( K'Address );
end ACTUAL_TEST;
Text_IO.Put_Line("Testing complete.");
End Test;
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: System.Address to Access to function/procedure conversion
2013-07-28 21:31 ` Maciej Sobczak
@ 2013-07-29 6:26 ` Tarek Ghaleb
0 siblings, 0 replies; 15+ messages in thread
From: Tarek Ghaleb @ 2013-07-29 6:26 UTC (permalink / raw)
On 2013-07-28, Maciej Sobczak <see.my.homepage@gmail.com> wrote:
>> Given an Address of a function/procedure, how can you call it
>> or convert the address to an access?
> This article can be helpful:
> http://www.inspirel.com/articles/Polymorphic_Callbacks_Ada_Cpp.html
> The article goes even further than what you describe, as it shows
> polymorphic (object-oriented) callbacks, so in your case the actual
> solution might be one or two details simpler. In any case, it uses
> System.Address and standard Ada conversions to do the work.
Yes, the article is very relevant to what I'm doing. It's very
interesting. Especially, that it's about callbacks and C++, which is
exactly what I'm dealing with. Thanks for the link.
Tarek.
--
Rotten wood cannot be carved. -- Confucius, "Analects", Book 5, Ch. 9
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: System.Address to Access to function/procedure conversion
2013-07-29 3:27 ` Shark8
@ 2013-07-29 7:06 ` Tarek Ghaleb
0 siblings, 0 replies; 15+ messages in thread
From: Tarek Ghaleb @ 2013-07-29 7:06 UTC (permalink / raw)
On 2013-07-29, Shark8 <onewingedshark@gmail.com> wrote:
> On Sunday, July 28, 2013 4:54:27 PM UTC-6, Tarek Ghaleb wrote:
>> On 2013-07-28, Shark8 wrote:
>>
>> >> I agree completely. Using C convention is the way to do it. But is it
>> >> *possible* to call a function using its address? (even if not a such a
>> >> great idea)
>>
>> > Yes. It's actually absurdly easy. Here's a sample of how to do it in
>> > Ada 2012, the same will work in earliet versions of Ada using
>> > Pargmas... all the way back to 83, IIUC.
>
> Oops; a little overzealous there.
> You have to use attribute definition clauses, which IIRC came in Ada 95.
> Below compiles and runs in GNAT using Ada83-mode:
>
> -- Pragma Ada_2012;
> Pragma Ada_83;
> Pragma Assertion_Policy( Check );
>
> With
> Text_IO,
> System;
>
> Procedure Test is
>
> Begin
> Text_IO.Put_Line("Starting Test:");
>
>
> ACTUAL_TEST:
> declare
>
> -- Note: Pragma CONVENTION is non-standard.
> Procedure K;
> Pragma Convention( C, K );
>
> Procedure K is
> begin
> Text_IO.Put_Line( "K was called" );
> end K;
>
> Procedure Execute( Addr : System.Address ) is
> -- Note: Pragma IMPORT is non-standard.
> Procedure Stub;
> Pragma Import( C, Stub );
>
> -- Note: The Ada 83 LRM, 13.5 (Address Clauses) gives the following:
> -- for CONTROL use at 16#0020#; -- assuming that
> -- SYSTEM.ADDRESS is an integer
> -- with the following warning:
> -- Address clauses should not be used to achieve overlays of
> -- objects or overlays of program units. Nor should a given
> -- interrupt be linked to more than one entry. Any program using
> -- address clauses to achieve such effects is erroneous.
>
> Use Text_IO;
> Begin
> Put_Line( "Executing:" );
> Put( ASCII.HT );
> Stub;
> End Execute;
>
> begin
> Execute( K'Address );
> end ACTUAL_TEST;
>
>
> Text_IO.Put_Line("Testing complete.");
> End Test;
That's an _exhaustively_ thorough answer :-))
Actually, I've used
For A'Address Use B'Address;
before, but never thought of using it for a subprogram: the way you
showed in the example above.
Tarek.
--
Rotten wood cannot be carved. -- Confucius, "Analects", Book 5, Ch. 9
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2013-07-29 7:06 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-28 15:27 System.Address to Access to function/procedure conversion Tarek Ghaleb
2013-07-28 16:14 ` Dmitry A. Kazakov
2013-07-28 19:05 ` Tarek Ghaleb
2013-07-28 19:23 ` Simon Wright
2013-07-28 22:03 ` Tarek Ghaleb
2013-07-28 20:03 ` Dmitry A. Kazakov
2013-07-28 21:13 ` Shark8
2013-07-28 22:54 ` Tarek Ghaleb
2013-07-29 3:27 ` Shark8
2013-07-29 7:06 ` Tarek Ghaleb
2013-07-28 17:19 ` Jeffrey Carter
2013-07-28 19:05 ` Tarek Ghaleb
2013-07-28 20:04 ` Jeffrey Carter
2013-07-28 21:31 ` Maciej Sobczak
2013-07-29 6:26 ` Tarek Ghaleb
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox