CHUG is a replacement for SWIG.
What is wrong with SWIG?
- SWIG is too complicated, and therefore difficult to debug.
- SWIG adds a layer of memory management.
How is CHUG better than SWIG?
- CHUG is simpler. CHUG does not parse a C++ header. Instead, it generates the C++ header. The user can then implement it as he sees fit.
- CHUG encourages a better memory model.
SWIG handles smart-pointers the way it handles all copyable objects: It allocates a copy on the heap and retains (some representation of) a pointer to that new memory in the target language.
CHUG has special handling for
boost::intrusive_ptr<>
, which allows the wrapped object to contain the raw pointer address.
Couldn't a SWIG typemap handle
boost:intrusive_ptr<>
in a similar way?
Yes, but see #1.
Is it really Humanoid?
Maybe not, but see IMDB.
- Parse API spec. The 'grammar' is Java. CHUG uses Java reflection to discern the API.
- Dump a YAML representation of the API. This CHUY file allows the rest of CHUG to be written in any language.
- Parse YAML and ...
- Dump a C++ header for the implementation.
This is the under-layer. - Dump a pure ANSI C (
extern "C"
) version of the API.
This is the native layer. It is implemented in C++ in terms of the under-layer. - For each target language, dump an implementation of the API.
These are the over-layers. They use only language-specific features and the C layer.
- Dump a C++ header for the implementation.
This multi-step approach makes the whole process easy to debug and customize.
- HUG
- Humanoid Unwrapping Generator
- Given a Java Interface or Abstract class, produce a CHUY file (CHUG/YAML format).
- PLUG
- C Plus Plus Under-Layer Generator
- Given a CHUY file, produce the C++ under-layer.
- NAG
- Native API Generator
- Given a CHUY file, produce the ANSI/ISO C native layer.
- SWOG
- Simplified Wrapper Over-layer Generator
- In contrast to SWAG.
- Given a CHUY file, produce an over-layer for a given target language.
- Simplified Wrapper Over-layer Generator
- Under-layer: C++
- Header is generated by PLUG from a CHUG YAML file.
- Classes derive from a ReferenceCounter (configurable) and
extern "C" struct
s, in addition to the user-defined hierarchy. boost::intrusive_ptr<>
is used by default for pass-by-copy.
- Classes derive from a ReferenceCounter (configurable) and
- Must be implemented by the user.
inline
methods are encouraged, through a.i
include file.
- Header is generated by PLUG from a CHUG YAML file.
- Native layer: ANSI/ISO C
- Implemented in C++, with
extern "C"
linkage for its interface. - Uses the under-layer, including
inline
methods.
- Implemented in C++, with
- Over-layer: Ruby, Python, C++, Java, etc.
- Implemented in the target language, using the target language's native API.
- Java: JNI
- Python:
ctypes
- Perl: Possibly
P5NCI
,FFI
(which uses libffi),C::DynaLib
, orFFI::Raw
. - Ruby: ?
- C++:
#include
native layer API
- A plug-in architecture allows customization, including the eventual use of more efficient APIs (e.g. Perl XS or Python C API), using either the native layer or the under-layer directly.
- Implemented in the target language, using the target language's native API.
WTF? Did you say "C++"?
Yes, we did.
That's crazy talk! Why would I want to generate C++?
Because a well-written C++ library leaves too much exposed, by the nature of C++. A shared library should hide both data members and virtual methods so that minor revisions can be swapped in safely.
This work is distributed under the MIT license. See "LICENSE" file.
See the wiki.