0

Recently, I came across a safety critical system that uses only Ada. The system provides about 3 packages with about 200-300 functions in each package as source.

I need to access almost all of these function in another software system (very nice and neat) that is completely written in C/C++.

Goal: I need to expose these Ada functions to C/C++.

I understand I can use pragma Export() construct to export the functions and interfaces.C package to convert parameters between C and Ada.

But, I was wondering if there's an easier or more scalable way to do this?

  1. Maybe expose the complete package somehow?
  2. Or develop an RPC Architecture?
  3. Or use a tool that creates the C/C++ declarations and Type Conversions?

It would really help if somebody with similar experience could point me in the right direction.

Remember I am not looking for an Ada to C translator

Tony
  • 49
  • 4
  • 1
    pragma Export, or the related aspects if you're working with Ada 2012, are what you're looking for, at least by my understanding of your goal. You can write a script to generate those exports for you; that's what I'd do. – Patrick Kelly May 31 '17 at 21:07
  • Sorry for confusion, I mean either C or C++ will do. Preferably C++. – Tony May 31 '17 at 21:09
  • @PatrickKelly : Can you please elaborate on how you use the script? I have never used a script before to expose ADA functions to C. Or may be share a simple script. Thanks – Tony May 31 '17 at 21:18
  • C and C++ are different languages with typically different ABIs and interfaces. The ABIs are also platform-specific. As asked, your question is far too broad. I t does not show any research on your side (apart from some `pragma` which is not standard. As a sidenote: if Ada was picked for safety reasons, now using C or C++ definitively will break the safe chain. "Nice and neat (and pinted in pink)" are certainly not major preferences in a safety critical environment. – too honest for this site May 31 '17 at 21:30
  • 1
    @Olaf Since when is `pragma export` not standard Ada? It can be found in the current standard right here: http://www.ada-auth.org/standards/aarm12_w_tc1/html/AA-J-15-5.html – SiggiSv May 31 '17 at 21:56
  • @SiggiSv: Sorry, I though OP means the C-preprocessor `#pragma`. That's the problem with too broad and cross-tagged questions. Anyway, there is something similar required on the C and C++ side, too. – too honest for this site May 31 '17 at 22:00
  • @Tony I just mean one you write up. Exactly what language used would be whatever you're comfortable with. This is too dependent on how you want to expose the functions and procedures, so I can't give you a generic script. But basically you just need to insert a line after each, with pragma export(stuff...). Exactly like you would manually, but in the script you can do things like yank the name of the procedure, reformat it C++ style, and place the new name in the export. – Patrick Kelly May 31 '17 at 22:30
  • @olaf The C++ part of the system is also verifiable and certifiable as per applicable safety standards. Its just that some parts of the system have a class of safety requirements that can only be met by Ada. I do understand the ABI interface and have some working set of API calls from C. It's just not scalable to add 1000 pragma export statements and translate parameters. – Tony May 31 '17 at 23:28
  • @Tony: There is always Python … just write a small Python prgramm to parse the Ada code and add the pragmas as required (I refrain from using regexpr only; Some guru might provide you a some 100 chars sed construct, but that's not my thing). – too honest for this site May 31 '17 at 23:34
  • 2
    You might get more traction over on [comp.lang.ada](https://groups.google.com/forum/#!forum/comp.lang.ada). Here, the question is in danger of being closed: [help/on-topic]. That said, since the existing Ada is safety-related you probably won’t find awkward things like tagged types, access-to-subprogram, generics in the interface. If noone comes up with a tool, I’d look at making an ASIS-based one: my [ASIS2XML](https://sourceforge.net/projects/asis2xml/) (the release is out of date, get the Code), or there’s one for GNAT (`gnat2xml`, supported by `gnat2xsd`) buildable from their ASIS archive. – Simon Wright Jun 01 '17 at 07:20
  • Thanks Simon, I will post the question there too and check out sources you have mentioned. – Tony Jun 01 '17 at 13:37
  • @Tony -- Did you try adding "with Convention => C_Plus_Plus, Export" to the package heading? (I'm assuming you're using Ada 2012.) -- I'd like to know if that worked for you. – Shark8 Jul 19 '17 at 23:10

1 Answers1

1

You could try adding the Export and Convention => X aspects to the package if you're using an Ada 2012 compiler; example:

Package K with Export, Convention => C_Plus_Plus is

    Function A( Input_1, Input_2 : Integer ) return Integer;

End K;

This actually compiles, though since I don't have any C++ or C mixed-source projects to try this on I can't tell you if the results are strictly-speaking usable from the C++ side.

If that doesn't work, perhaps a better method would be to create a package especially for exporting the functions (and types) that will be used on the C++ side.

With
System,
Interfaces.C.Strings,
Interfaces.C.Pointers;

Package K with Convention => C_Plus_Plus is

    -------------
    --  TYPES  --
    -------------

    Type CPP_Window_Handle is Private;
    Subtype CPP_String is Interfaces.C.Strings.chars_ptr;

    --------------
    -- MODULES  --
    --------------

    Package UI_Module is
        Procedure Set_Title( Window : CPP_Window_Handle; Text : CPP_String )
        with Export;
    End UI_Module;

Private
    Package STUB_TYPES is
        Type Window is tagged null record;
    End STUB_TYPES;
    Use STUB_TYPES;

    Type CPP_Window_Handle is not null access Window'Class
    with Convention => C_Plus_Plus, Size => Interfaces.C.int'Size;

End K;

Implemented as:

Package Body K is

    Package STUB_FUNCTIONS is
        Procedure Set_Window(Object : in out STUB_TYPES.Window'Class; Text : String) is null;
        --'
    End STUB_FUNCTIONS;

    Package Ada_Dependencies renames STUB_FUNCTIONS;

    Package Body UI_Module is
        Procedure Set_Title( Window : CPP_Window_Handle; Text : CPP_String ) is
            function Value (Item : CPP_String) return Interfaces.C.char_array
              renames Interfaces.C.Strings.Value;
            function Convert(Item     : Interfaces.C.char_array;
                             Trim_Nul : Boolean := True) return String
              renames Interfaces.C.To_Ada;
        Begin
            Ada_Dependencies.Set_Window(
              Object => Window.all,
              Text   => Convert( Value( Text ) )
          );
        End Set_Title;

    End UI_Module;

End K;
Shark8
  • 4,095
  • 1
  • 17
  • 31
  • 1
    This is similar to this: https://stackoverflow.com/questions/42938883/interface-ada-dynamic-library-with-java-using-jna-and-adas-interface-c-packages/42938971#42938971. As @Shark8 stated, you can either add the `pragma export` on the methods you want to expose, or add a routing layer written with `pragma export` that makes the effective call to Ada procedures/functions. The additionnal layer can be useful is you have some types transformations to do : for isntance, if you have types with discriminents in inputs of your ada services. Since Ada structures can't always be mapped easily with C/C++ – LoneWanderer Jun 13 '17 at 19:13