1

I have a question about a way to call a "C" function that is in a ROM, looking for a way to do this without involving link-time changes.

For example, we know the "C" function:

int my_func(int a); 

is located at address 0xFFFF_AAAA;

so we try:

type ROM_my_func is access function (a : Interfaces.C.int) return Interfaces.C.int;

pragma Convention (C, ROM_my_func);

ADA_my_func : ROM_my_func := 16#FFFF_AAAA#;

The error I can't get around is the assignment of ADA_my_func, unsure if there is a typecast, and an attempt at using System.Address_To_Access_Conversions did not prove successful either.

Any pointer(s) to examples and/or help would be greatly appreciated.

1 Answers1

4

If you’re using a modern GNAT and Ada2012 you can say

function My_Func (A : Interfaces.C.Int) return Interfaces.C.Int
with
  Import,
  Convention => C,
  Address => System'To_Address (16#ffff_aaaa#);

Note that the System’To_Address is GNAT-specific; you could use System.Storage_Elements.To_Address.

I ran a program using this under GDB and got

(gdb) run
Starting program: /Users/simon/tmp/so/asker 

Program received signal SIGSEGV, Segmentation fault.
0x00000000ffffaaaa in ?? ()

so it’s clearly done the Right Thing.

Without using Ada2012 aspects, you could write

function My_Func (A : Interfaces.C.Int) return Interfaces.C.Int;
pragma Import (C, My_Func);
for My_Func'Address use System'To_Address (16#ffff_aaaa#);
Simon Wright
  • 25,108
  • 2
  • 35
  • 62