The Automatic Component Toolkit (ACT) is a code generator that takes an instance of an Interface Description Language file and generates a thin C89-API, implementation stubs and language bindings of your desired software component.
You might not know that yet, but this toolkit is the ultimate solution for you if
Not using ACT for any of these purposes will either make you one of those three things:
The IDL file defines the types and functions of your API and serves as the source for the automatically generated Code. The exact schema of the IDL and explanation of each element is described in Documentation/IDL.md.
A thin C89-API is a C header file that declares all functions, structs, enums and constants exported by your software component. The C89-API unambiguously defines the binary interface (ABI) of the component.
An implementation stub is a collection of source files in a certain programming language L that implements
A language binding of the component for programming language C implements the classes, enums, methods, ... defined by the IDL by calling the functions exported by your component via the thin C89-API. A consumer of your component only needs to include the language binding relevant for them and not worry about the C89 interface or the underlying implementation.
1) Download the precompiled binaries of from one of the releases
2) Write an interface description file idl_file.xml
for your desired component
3) Generate implementation stubs and language bindings for your component:
act.exe idl_file.xml
4) Integrate the generated code in your project
You are probably best of starting of with our extensive Tutorial.
Alternatively to 1) build ACT from source (master for a released vesion, develop for the latest developments):
Build\build.bat
on Windows or Build\build.sh
on UnixACT supports generation of bindings or implementation stubs for C++, C, Pascal, Golang, NodeJS and Python3. However, not all features of the IDL are yet supported by the individual binding or implementation language:
Binding | Status | Operating Systems | class | scalar type | struct | enumeration | string | basicarray | structarray | Callbacks | Error Message Propagation | Injection |
---|---|---|---|---|---|---|---|---|---|---|---|---|
C++ | mature | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | + |
C++ Dynamic | mature | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | + |
C | mature | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | - |
C Dynamic | mature | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | - |
Pascal | mature | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | + |
Python3 | complete (but not very pythonic) | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | + |
Golang | partial support | Win, Linux, MacOS | in,return | in,out,return | ? | ? | ? | ? | ? | - | - | - |
NodeJS | partial support | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | ? | ? | - | + | - |
C# | experimental | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | - | - | - | + | - |
PHP | not implemented | Win, Linux, MacOS | - | - | - | - | - | - | - | - | - | - |
Implementation | Status | Operating Systems | class | scalar type | struct | enumeration | string | basicarray | structarray | Callbacks | Journaling | Error Message Propagation | Injection |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
C++ | mature | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | + | + | + |
Pascal | mature | Win, Linux, MacOS | in,return | in,out,return | in,out,return | in,out,return | in,out,return | in,out | in,out | in | - | + | + |
A complete example of the implementation and usage of an ACT component can be found in Examples/Primes. This folder also contains a complete Tutorial to set up this example project.
A very clean approach to creating software components is the hourglass pattern for APIs. The rationale is to pipe any domain code with a thick API through a C89-interface, narrowing exported types and functions to C89-types and methods, and thereby also catching all exceptions.
Domain-Code with thick API
\ (templates, complex classes, custom /
\ exceptions, custom control flows/
\ ... /
\ /
Narrow C89-interface (thin API)
(return values,
error codes,
error strings)
/ \
/ \
Language bindings in any other language;
Thick API
This enables producers of libraries to use their own programming paradigms and styles, without affecting their consumer and results in a great isolation of code (and responsibility) between library-producer and -consumer. Due to the very clear interface, such libraries are very easy to integrate in existing projects.
A very detailed introduction the topic this presentation: https://www.youtube.com/watch?v=PVYdHDm0q6Y
Generating (and maintaining!) the required layers of interfaces (language bindings, thin API and domain code-API) and their consistency is labor-intensive and error prone if it is not automated. That's what ACT is here for.
The Automatic Component Toolkit is an open source project.
Contributions are welcome and we are looking for people that can improve existing language bindings or create new bindings or implementation stubs. Have a look at the contributor's guide for details.