 Yes, thank you everyone for coming today. I'm going to talk about cap you later our Ada binding generator generator for C++ code so what is our objective we want to Use Ada components in C++ environments, or maybe use C++ libraries with with Ada and and While writing a binding is technically relatively easy if you have a large API It's quite cumbersome and you need to do a lot of stuff manually that could be automated And they are already already existing solutions. So the GCC provides a binding generator GTK Ada uses a binding generator for the GTK code and And also there's a project on GitHub called headmaster, which is which generates binding for C code So why do we want to use and want to reinvent the wheel? Well, all of these solutions have drawbacks that we need to overcome. So the GCC binding generator Generates uncompilable code, which is quite bad because we would have to build a post processor anyway that fixes the errors the GCC makes Also, they don't support things like templates and Some symbols just get just are leafed out because GCC says well, this isn't in this isn't a valid Ada symbol And if we wanted to fix GCC itself We would probably have to maintain our own fork of GCC, which isn't really feasible in the long run Also GTK Ada This is really really project specific and they just generate GTK bindings from GTK's own Specifications and Also, they have no C++ support the same goes for headmaster, which is really an only C project So what do we want to do? Well, we want to automatically generate Ada bindings from C++ headers We want an API layout that keeps the types and that which has a semantic mapping So if I have a namespace and a class called A and B and maybe a subclass called C If you use that in Ada, this should also be A dot B dot C and not any further Packaging around it, but we really want to use the binding as native as possible Also, we need to automatically generate all the import linker symbols And we have to take name collisions because if I have a variable that is called begin in C++ This won't probably work in Ada because it's a keyword So we have to get that out of the code or really rename it in a valid way And also since we are often using with spark the generated bindings should be a spark compatible as possible so if we use function pointers in C++ we won't get spark code, but for Normal class that doesn't use these things spark is possible So what are the C++ features that are hard object orientation? Okay, we have this that in Ada, but we want static and dynamic dispatching to work So we have to look in C++ if we have a v-table and if we use virtual functions And if we need to use intact type in Ada also Yeah, we want to use C++ templates which is really and which is a concept that doesn't exist in Ada So this is going to be interesting also where re-addict templates Which means we have a C++ template that has an yet unknown amount of arguments And you can instantiate it with just as many arguments as you want to And we want to automatically call constructors and destructors So if you if you have a record in Ada you can just take it and it's there But in C++ the class needs to be constructed by the constructor and also if it goes out of scope It needs to be destructed and if it goes out of scope in Ada this doesn't happen So we have to fix this somehow This is our Architecture so the upper layer is the data and the lower layer our components We have the C++ headers and just pass them with lip clang because it's easy That gives us an abstract syntax tree. So basically the C++ code as a free like structure and in memory We have a converter that and where we enrich this data So we have to instantiate the C++ templates by our own because the the instances are not in This in this tree and if we find a template and we find a template use we have to create an instance of this template that Binds to the actual instance that is generated by the GCC when compiling the C++ code With our intermediate representation where all these data is Existing we can then call a generator that takes the data and just Generates Ada snippets and those snippets are then put together to a complete Ada specification So, how does this look? we have a small class the namespace and a class and we have a public a Public member and just the constructor and the generated code is a package a that is that represents the namespace and a package B That represents the class and since we don't want to have state in our classes But we want to have objects and the class object itself is a limited record Which then contains the member variable and the constructor Is an auto-generated function that returns this member this type With the and the pragma C++ constructor is from Knot Which tells Knot, okay, this is our constructor and we have and here we have to supply the constructor symbol of the of the object file and Then if we call If we call this function that the C++ constructor gets called and returns us an initialized object How do we fix the naming problems I told further so At first we apply Ada casing this means as I don't know if this is in the standard, but it's good practice so upper case at each beginning a word and Delimited by underscores also if you have invalid things like leading underscores or double underscores be in just insert an X and also keywords are Prepended with an X if we have unmappable characters like this German upload We replace it with the utf8 sequence And hope that nobody else in the C++ code ever did use this variable name Yeah, so that's like a little more advanced thing we have a C++ template So C++, I hope I hope everyone knows what C++ templates are and how they work a little bit. So they are basically Just a code that isn't in the object file, but once you instantiate it this code gets copied with integer as a S as type and then if you instantiate again It gets again copied and those are two different things then and for Ada We have to somehow map this since we don't have templates we just use some name wrangling So the class a gets a and then underscore t for template and then underscore int for the integer here And the other thing is a package a underscore t and underscore t for B for the instance of B And then we have two separate things Which we can use from Ada and if we call If we if we call something from this package actually this instantiation of the template will be used So what are the challenges? Well, the name is caping as I said you can just push all the names into C++ and hope that it collides somewhere after our name wrangling So because the C++ identifiers have a complete superset of the Ada identifier rules So you can just do anything that isn't allowed in Ada Also real C++ generics So the problem is C++ generics aka templates are a compile time construct while Ada generics Runtime construct so if you wanted to use templates as you use them in C++ You would have to use to add some pre-processor to Ada that does that But I use I special I also use it up because it doesn't have a pre-processor and Using Ada generics to do things that are usually done at compile time isn't really working So you can't say you can't use Ada generics to map to templates and we have circular dependencies in C++ and C++ code so you can generate a forward declaration use it and then Declare something else. I have an example for this So you have a forward declaration class x this just tells okay We have a class x that is something and then we have a class y that uses a reference So this class x and then we have have the class x defined that again uses the class y So we have a circular dependencies because these both classes depend on each other in this case We only have a reference so we can fix this by a so-called limited width Those are two files so think a line here which divides those files and when we In this limited limited width gives us an Ada the possibility to do some kind of circular dependencies so we can We can define a riff for an axis type of x.class which is defined in the x package But we can only define an axis type so we can't use x.class directly But we have our reference that is used here And then we can just with y in the x package and use it regularly as an object So the conclusion of this we can map complex C++ scenarios in Ada Also advanced features such as templates can be used to some extent We think that this is sufficient for a real-world use in the most cases But some features are just not doable or really really really hard to do So yeah, it's still under heavy development There are quite some bugs we need to do and we don't for instance. We currently don't have every support So this is some quite Important feature that we need to add But we support namespaces classes and templates type devs And you can find the project on github If you want to help us in doing all these other hard thing things And now I have a small demo for you. Yeah, you can see this So we have a we have a simple Simple C++ Library called number that just is a template of the class number and it has a volume Is this large enough or should I? Maybe make And You have a function at that adds something to the value and a functional value that Returns the volume and now we want to use this in Ada. So Since this is a dummy library and there's no and they're only there's only this header file we need to We need to trick the GCC to instantiate our template because we need to the compiled code at the end to link Against Ada. So this is a dummy class that just tricks GCC Into creating actually actually creating an object with all these functions That contains all these functions. Otherwise this there they would just be not existent Yeah, and we need to create an object so we have to instantiate this once in In this in a cc file. So we get something to link against this This is just this isn't probably some this is something you probably don't need if you use a real word library and Yeah, let's Create our example So we call it our number and we name it example, which is just the top level package Name it gets and now we have our example dot ads that uses interfaces dot c for obvious reasons It uses spark and we have some type renames and More type renames and there there's our package number, which is a template instance of int We have our private while you hear this private what this happens because Because we don't want to alter all to our values in Ada that are private in C++ So we want to somehow keep this mapping, but we still need to have this while you in the record otherwise the C++ Can you see the cursor? Yes Otherwise this the C++ The GCC will create a wrong memory memory layout. So we have to keep this And we have the constructor with a symbol and we have an ad function with a symbol Let's call it a little bit And we have yes, we have the ad function And the value function and there's our dummy class starting, but this isn't really interesting so and now we have our Example program so this is just boilerplate code that reads That reads command line arguments and here we use it So we say okay a is an example number gint class and it is created by the constructor with With the value of x and then we add the second argument the y to this To this object and then just we just return Return its volume. So and here we put out the volume And if I compile this I get a little program called at this which will just Add two numbers and like five and four and we get nine So, yeah, that's it. So, thank you. That's yeah, I'm finished Are there questions? Not like because you could technically try to go with type and then just Like that is that because class in c++ also provides a namespace and you want to have this yes Yes, because The ad function for example in c++ you call this ad function with class name or with object name dot add and Because if you don't do that and you have two classes that implement add You would collide an ad if you don't encapsulate this Generics, I mean templates and generics are not the same sure Wouldn't it be I mean you can as far as I can see Implementing templates as generic as like generic package could be actually even simpler going the other way around Well The problem is templates are compile time and adagenerics are runtime Yeah, I thought about the thing Template Generic package and then instantiation of this package This specific type because that's like the main use the intended use on the other side and intended use on the c-side It's true that like then people abuse this stuff like horribly especially in other like to make like proper multiple inheritance Yeah, that's true, but due to the technical differences It's really hard to map that correctly because you have to move something that is usually happening runtime to the compile time And then you lose the the possibility to make for example to instantiate adagenerics with runtime variables That is not going to work with c++ templates at all No, no, we are only generating the bindings Yeah, the bindings that's what I mean if your task was the opposite that would be a severe limitation You cannot with c++ templates really completely emulate other generics But it seems to me that other generics should be able to give you most of the templates Can we talk after? Yeah, so you had We are building this to use Ada in the genote OS framework Which is an operating system framework built on c++ and uses all the extensive templating and stuff So, yeah, I would say this is quite complex. The genote guys are sitting Right there so you can ask them about the about the genote project Yeah, I would say this is the most complex thing we are currently doing. It's not working completely, but some things are already mappable You had a Okay, Qt is something else because they have their own pre-processor stuff Yeah the point is and The problem is in c++ if you create in just a class as you have seen here It doesn't have a v-table which means the memory mapping starts at zero and if you add a tag the memory memory mapping starts at byte 8 and The same is the other way around if you use a v-table For example due to a virtual function the memory mapping in c++ starts at byte 8, which means that C++ classes that use virtual functions are tagged classes in Ada and those that are not using virtual functions or not They are not derived from virtual functions Are not using tag types in Ada Yes Yes Yes Integer We use the interfaces.c for the types we just rename Here it is mapped we convert it to our example.int which Which is a subtype of interfaces.c the point that we rename all these types because we want to keep our own name space in if you if you Convert if you generate bindings for a project or everything that comes from here is its own namespace so we rename it I've done as a native function that returns the struct and Got this struct in a C++ map binding so the other way around and this worked I can't I can't say why it shouldn't work. So in theory you should just be able to put a struct in the function Yes, okay, so if I go down here Convention C++ yes Okay To some extent yes on the other hand I'm not able to rewrite everything that I use in C++ that is currently written C++ in Ada So I'm probably better by importing some things and Saving sometimes. Yeah, thank you