Skip to content

Latest commit

 

History

History

examples

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Examples aka CIB Architecture Details

We will see bits and peices of CIB architecture through code generated by cib. We will start with trivial example and slowly build on that to understand what CIB architecture requires in more complex cases. Except the declaration of proxy classes that client's will use, all other code generated by cib are solely for compilers. But we will look into generated code to understand CIB architecture.

All examples mentioned below are real programs, however tiny, they are working piece of code and are actually part of automated tests of cib:

  • Almost all examples contain a library and a client executable.
  • Library consists of public headers and source files.
  • Most functions simply return an int.
  • cib tool is used on public header that
    • generates glue code for library and clients.
    • generates cibified headers that becomes part of the SDK.
  • Client is an executable that tests correct behavior of library.

Please go through the examples to know the details of CIB architecture.

CIB Terminology

Inline Class

A class that has all methods inline. For example a template class is surely an inline class.

Shared Class

A C++ class whose reference cross component boundary: When there exists a way for client to receive a pointer or reference of a C++ class from library then such class is called as a shared class. The reason for this is that the client can get same reference multiple times and so the instances are shared.

Facade Class

A C++ class that acts as facade for other classes: A class that has at least one public virtual method and there exists a way for client to receive a pointer or reference of this class from library. Since the returned object can actually be a type of any of derived class the return type acts as facade for all it's derived classes.

Interface Class

A C++ class that has public virtual method and there exists a way for library to call methods of an object of class defined by client.

Proxy Class

For each public class of a library CIB produces another class with same name and behaviour. Such client usable classes are called proxy classes because they act as a proxy of original class to the client. There are 2 kinds of proxy classes:

  1. Isolated proxy class, that uses bridge patern (or pImpl pattern) across component boundary.
  2. Layout sharing proxy class. Both original and proxy class share same object layout.

When simply proxy class is used then it always means isolated proxy class.

Implementation Details

Parsing Technique

We use cppparser to parse C++ headers. Clang can be an option but since we do not need full and complete compiler level type resolution clang is not suitable for us. For example if a function is declared as:

void ExampleFunction(wxInt32 i);

cib doesn't need to resolve wxInt32. In-fact if cib resolves it completely then it will be a problem because wxInt32 can be an int, or a long depending upon platform or compiler and cib really should produce same definitions regardless of compiler or platform.

Limitations of CIB Architecture

CIB Architecture is good for ensuring ABI compatibility and stability. But unfortunately these goodness are not free. CIB architecture has limitations too:

Limitation Reason Workaround, if any
Mandatory creation of proxy objects The core philosophy of CIB is to not share internals with other components. For that reason each component have their own objects. The library objects used by client are used through proxies which are created at client side and act as if they are client side objects. So, for every library side object that client want to use, a corresponding proxy object is also created. It adds up to use of more memory and cost runtime performance too. Use layout sharing proxy wherever applicable
Objects of library are always created on heap by the client This is not true for layout sharing proxy classes but when client creates an object of isolated proxy object the corresponding object on library side is always created on heap. Use layout sharing proxy wherever applicable
Increased binary size and memory usage Because of proxy objects and their special implementation using MethodTable binary size and memory usage of both library and client increases. Use layout sharing proxy wherever applicable
Impact on runtime performance CIB layers costs runtime performance too because there is no inline function across component, multiple function calls involved for a single call across component, and cross component function calls happen always through function pointer. In practice these costs may not be significant.
No raw array of objects can cross component boundary in most cases Except when the proxy class is layout sharing type it is not possible to share raw array of objects across component boundary. Return a container object instead or use layout sharing proxy wherever applicable.