Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,9 @@ Djinni generator parses an interface definition file and generates:
- C++ implementations of types (enums, records)
- Java implementations of types
- Objective-C implementations of types
- Python implementation of types
- C++/CLI implementation of types
- C++ code to convert between C++ and Java over JNI
- C++ code to serialize/deserialize types to/from JSON
- Objective-C++ code to convert between C++ and Objective-C
- Python and C code to convert between C++ and Python over CFFI
- C++/CLI code to convert between C++ and C#


## Installation
Expand Down
56 changes: 3 additions & 53 deletions docs/cli-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,6 @@ djinni \
\
--objcpp-out OBJC_OUTPUT_FOLDER \
\
--py-out PYTHON_OUTPUT_FOLDER \
--pycffi-out CFFI_OUTPUT_FOLDER \ # Required for Python support
--pycffi-package-name PyCFFIlib \
--pycffi-dynamic-lib-list mylib \
--c-wrapper-out C_WRAPPER_OUTPUT_FOLDER \ # Required for Python support
\
--idl MY_PROJECT.djinni

```
Expand Down Expand Up @@ -118,32 +112,10 @@ djinni \
| `--objc-extended-record-include-prefix <prefix>` | The prefix path for `#import` of the extended record Objective-C header (`.h`) files |
| `--objcpp-namespace <prefix>` | The namespace name to use for generated Objective-C++ classes. |

### Python

| Argument | Description |
|--------------------------------------|-------------------------------------------------------------------------|
| `--py-out <out-folder>` | The output folder for Python files (Generator disabled if unspecified). |
| `--pycffi-out <out-folder>` | The output folder for PyCFFI files (Generator disabled if unspecified). |
| `--pycffi-package-name ...` | The package name to use for the generated PyCFFI classes. |
| `--pycffi-dynamic-lib-list ...` | The names of the dynamic libraries to be linked with PyCFFI. |
| `--py-import-prefix <import-prefix>` | The import prefix used within python generated files (default: "") |

### C wrapper

| Argument | Description |
|-------------------------------------------|----------------------------------------------------------------------------------------|
| `--c-wrapper-out <out-folder>` | The output folder for C wrapper files (Generator disabled if unspecified). |
| `--c-wrapper-header-out <out-folder>` | The output folder for C wrapper header files (default: the same as `--c-wrapper-out`). |
| `--c-wrapper-include-prefix <prefix>` | The prefix for #includes of C wrapper header files from C wrapper C++ files. |
| `--c-wrapper-include-cpp-prefix <prefix>` | The prefix for #includes of C++ header files from C wrapper C++ files. |

### C++/CLI

| Argument | Description |
|----------------------------------------|----------------------------------------------------------------------------|
| `--cppcli-out <out-folder>` | The output folder for C++/CLI files (Generator disabled if unspecified). |
| `--cppcli-namespace ...` | The namespace name to use for generated C++/CLI classes. |
| `--cppcli-include-cpp-prefix <prefix>` | The prefix for `#include` of the main C++ header files from C++/CLI files. |


### Yaml Generation
Expand Down Expand Up @@ -204,31 +176,9 @@ Possible values: `FooBar`, `fooBar`, `foo_bar`, `FOO_BAR`, `m_fooBar`.
| `--ident-objc-local` | `fooBar` |
| `--ident-objc-file` | `FooBar` |

#### Python

| Argument | Default |
|-------------------------|-----------|
| `--ident-py-type` | `foo_bar` |
| `--ident-py-class-name` | `FooBar` |
| `--ident-py-type-param` | `foo_bar` |
| `--ident-py-method` | `foo_bar` |
| `--ident-py-field` | `foo_bar` |
| `--ident-py-local` | `foo_bar` |
| `--ident-py-enum` | `Foo_Bar` |
| `--ident-py-const` | `FOO_BAR` |

#### C++/CLI

| Argument | Default |
|-----------------------------|----------|
| `--ident-cppcli-type` | `FooBar` |
| `--ident-cppcli-type-param` | `FooBar` |
| `--ident-cppcli-property` | `FooBar` |
| `--ident-cppcli-method` | `FooBar` |
| `--ident-cppcli-local` | `fooBar` |
| `--ident-cppcli-enum` | `FooBar` |
| `--ident-cppcli-const` | `FooBar` |
| `--ident-cppcli-file` | `FooBar` |




Example:

Expand Down
6 changes: 1 addition & 5 deletions docs/developer-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,7 @@ sbt "run
--cpp-out out/cpp
--java-out out/java/src
--jni-out out/java/jni
--objc-out out/objc
--py-out out/python
--pycffi-out out/cffi
--c-wrapper-out out/cwrapper
--cppcli-out out/cppcli"
--objc-out out/objc"
```

```bash
Expand Down
84 changes: 0 additions & 84 deletions docs/generated-code-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,93 +78,9 @@ Add all generated files to your build target, and link against the [djinni-suppo
Note that `+Private` files can only be used with ObjC++ source (other headers are pure ObjC) and are not required by Objective-C users of your interface.


## Python / C++ Project (Experimental)

Python support in Djinni is experimental, but ready to try out. It can generate code for bridging
C++ with Python 3.

For more information, you can check out the talk from CppCon 2015.
[Slides](https://bit.ly/djinnitalk2) and [video](https://bit.ly/djinnivideo2) are available online.

### Includes & Build Target

When bridging to Python, Djinni generates 4 types of output:

* `python` Generated Python classes and proxies for interacting with C++ via [CFFI](https://cffi.readthedocs.org/).
* `cffi` Python code run at build time to create a Python extension out of the C++ code.
* `cwrapper` A C interface implemented in C++ to allowing Python to interact with C++ classes.
* `cpp` The same C++ classes generated for all other Djinni languages.

Generated files for Python / C++ are as follows:

| Type | C++ header | C++ source | Python files | CFFI | C Wrapper |
|------------|----------------------------|------------------------------|---------------------|---------------------|----------------------|
| Enum/Flags | my\_enum.hpp | | my_enum.py | | dh__my_enum.cpp |
| | my\_enum+json.hpp :two: | | | | dh__my_enum.h |
| | | | | | dh__my_enum.hpp |
| Record | my\_record[\_base].hpp | my\_record[\_base].cpp :one: | my_record[_base].py | | dh__my_record.cpp |
| | my\_record[\_base]+json.hpp| | | | dh__my_record.h |
| | :two:| | | | dh__my_record.hpp |
| Interface | my\_interface.hpp | my\_interface.cpp :one: | my_interface.py | pycffi_lib_build.py | cw__my_interface.cpp |
| | | | | | cw__my_interface.h |
| | | | | | cw__my_interface.hpp |

- :one: Generated only for types that contain constants.
- :two: Generated only if cpp json serialization is enabled.

Additional C Wrapper files are generated for data structures; their names are encoded as:

dh__{list,set,map}_{encoded_type(s)}.cpp
dh__{list,set,map}_{encoded_type(s)}.h
dh__{list,set,map}_{encoded_type(s)}.hpp

See the in the table below a few examples:

| Type | C Wrapper |
|-------------------------|----------------------------------------|
| `list<i32>` | dh__list_int32_t.{cpp,h,hpp} |
| `set<string>` | dh__set_string.{cpp,h,hpp} |
| `map<i32, set<string>>` | dh__map_int32_t_set_string.{cpp,h,hpp} |

Add all generated C and C++ source files to your build target, and link it against the
[djinni-support-lib](https://github.com/cross-language-cpp/djinni-support-lib).

Compile the Python extension module (CFFI) by executing `pycffi_lib_build.py` while providing all C
Wrapper header files (`.h`) as arguments. The resulting shared library will enable Python to access
your C++ library through the CFFI bridge.

### Known limitations of the generator

* External types defined in YAML are not yet supported.
* Use of non-nullable pointers is not yet supported.


## C++/CLI / C++ Project

C++/CLI is a technology by Microsoft that provides interoperability of C++ with Microsoft .NET languages such as C#.
It is only supported on Windows.

Djinni generates a shallow C++/CLI wrapper around the C++ interfaces. Once compiled to a shared library, the resulting `dll`
just needs to be added to your C# project as reference, and you can call your Djinni interfaces from C# like any other .NET library.

### Includes & Build target

The following code will be generated for each defined type:

| Type | C++ header | C++ source | C++/CLI header/sources |
|------------|--------------------------|----------------------------|-------------------------------------|
| Enum/Flags | my\_enum.hpp | | MyEnum.hpp, MyEnum.cpp |
| | my\_enum+json.hpp :two: | | |
| Record | my\_record.hpp | my\_record.cpp | MyRecord.hpp, MyRecord.cpp |
| | my\_record+json.hpp :two:| | |
| Interface | my\_interface.hpp | my\_interface.cpp :one: | MyInterface.hpp, MyInterface.cpp |

- :one: Generated only for types that contain constants.
- :two: Generated only if cpp json serialization is enabled.

Add all generated files to your build target, and link against the [djinni-support-lib](https://github.com/cross-language-cpp/djinni-support-lib).

C++/CLI sources have to be compiled with MSVC and the [`/clr` (Common Language Runtime Compilation)](https://docs.microsoft.com/en-us/cpp/build/reference/clr-common-language-runtime-compilation?view=msvc-160) option.

## C++ JSON Serialization support

Expand Down
58 changes: 21 additions & 37 deletions docs/idl.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ my_cpp_interface = interface +c {
const version: i32 = 1;
}

# This interface will be implemented in Java, ObjC, Python and C# and can be called from C++.
my_client_interface = interface +j +o +p +s {
# This interface will be implemented in Java and Objective-C and can be called from C++.
my_client_interface = interface +j +o {
log_string(str: string): bool;
}
```
Expand Down Expand Up @@ -135,20 +135,6 @@ The available data types for a record, argument, or return value, and their equi
| `map<K, V>` | `System.Collections.Generic.Dictionary<K, V>` |
| `optional<T>` | `System.Nullable<T>` |

=== "Python"

| Djinni | Python |
|---------------------------|-------------------------------------------|
| `bool` | |
| `i8`, `i16`, `i32`, `i64` | |
| `f32`, `f64` | |
| `string` | |
| `binary` | object supporting the `buffer` interface |
| `date` | `datetime.datetime` |
| `list<T>` | `List` |
| `set<T>` | `Set` |
| `map<K, V>` | `Dictionary` |
| `optional<T>` | |


✱ *Primitives will be boxed in Java and Objective-C.*
Expand All @@ -163,13 +149,13 @@ Additional possible data types are:

An IDL file can contain 4 kinds of declarations: enums, flags, records, and interfaces.

* [**Enums**](#enums) become C++ enum classes, Java enums, ObjC `NS_ENUM`s, Python `IntEnum`s, or C# `System.Enum`s.
* [**Enums**](#enums) become C++ enum classes, Java enums, or ObjC `NS_ENUM`s.
* [**Flags**](#flags) become C++ enum classes with convenient bit-oriented operators, Java enums with `EnumSet`,
ObjC `NS_OPTIONS`, Python `IntFlag`s, or C# `System.Enum`s with the [`[Flags]` Attribute](https://docs.microsoft.com/en-us/dotnet/api/system.flagsattribute?view=net-5.0).
or ObjC `NS_OPTIONS`.
* [**Records**](#records) are pure-data value objects.
* [**Interfaces**](#interfaces) are objects with defined methods to call (in C++, passed by `shared_ptr`). Djinni
produces code allowing an interface implemented in C++ to be transparently used from ObjC,
Java, Python or C#, and vice versa.
produces code allowing an interface implemented in C++ to be transparently used from ObjC
and Java, and vice versa.

### Enums

Expand All @@ -182,7 +168,7 @@ my_enum = enum {
```

Enums are translated to C++ `enum class`es with underlying type `int`, ObjC `NS_ENUM`s with
underlying type `NSInteger`, Java enums, Python `IntEnum`s, and C# `System.Enum`s.
underlying type `NSInteger`, and Java enums.

### Flags

Expand All @@ -198,11 +184,11 @@ my_flags = flags {

Flags are translated to C++ `enum class`es with underlying type `unsigned` and a generated set of
overloaded bitwise operators for convenience, ObjC `NS_OPTIONS` with underlying type `NSUInteger`,
Java `EnumSet<>`, Python `IntFlag`, and C# `System.Enum`s with the [`[Flags]` Attribute](https://docs.microsoft.com/en-us/dotnet/api/system.flagsattribute?view=net-5.0).
and Java `EnumSet<>`.
Contrary to the above enums, the enumerants of flags represent single bits instead of integral values.

In the above example the elements marked with `none` and `all` are given special meaning. In C++,
ObjC, and Python the `no_flags` option is generated with a value that has no bits set (i.e. `0`),
In the above example the elements marked with `none` and `all` are given special meaning. In C++
and ObjC the `no_flags` option is generated with a value that has no bits set (i.e. `0`),
and `all_flags` is generated as a bitwise-or combination of all other values. In Java these special
options are not generated as one can just use `EnumSet.noneOf()` and `EnumSet.allOf()`.

Expand Down Expand Up @@ -234,7 +220,7 @@ records (so a record cannot contain itself).
#### Extensions

To support extra fields and/or methods, a record can be "extended" in any language. To extend a
record in a language, you can add a `+c` (C++), `+j` (Java), `+o` (ObjC), `+p` (Python), or `+s` (C#) flag
record in a language, you can add a `+c` (C++), `+j` (Java), or `+o` (ObjC) flag
after the record tag. The generated type will have a `Base` suffix, and you should create a derived
type without the suffix that extends the record type.

Expand All @@ -252,7 +238,7 @@ another_record = record {

For record types, Haskell-style "deriving" declarations are supported to generate some common
methods. Djinni is capable of generating equality and order comparators, implemented as operator
overloading in C++ and standard comparison functions in Java, Objective-C, Python and C#.
overloading in C++ and standard comparison functions in Java and Objective-C.

!!! note

Expand All @@ -275,15 +261,15 @@ my_cpp_interface = interface +c {
const version: i32 = 1;
}

# This interface will be implemented in Java, ObjC, Python and C# and can be called from C++.
my_client_interface = interface +j +o +p +s {
# This interface will be implemented in Java and Objective-C and can be called from C++.
my_client_interface = interface +j +o {
log_string(str: string): bool;
}
```

Interfaces are objects with defined methods to call (in C++, passed by `shared_ptr`). Djinni
produces code allowing an interface implemented in C++ to be transparently used from ObjC,
Java Python or C# and vice versa.
produces code allowing an interface implemented in C++ to be transparently used from ObjC
and Java, and vice versa.

#### Special Methods for C++ Only
`+c` interfaces (implementable only in C++) can have methods flagged with the special keywords const and static which
Expand Down Expand Up @@ -339,23 +325,22 @@ public:

#### Exception Handling
When an interface implemented in C++ throws a `std::exception`, it will be translated to a
`java.lang.RuntimeException` in Java, an `NSException` in Objective-C, a `RuntimeError` in Python,
or a `System.Exception` in C#.
`java.lang.RuntimeException` in Java or an `NSException` in Objective-C.
The `what()` message will be translated as well.

#### Constants
Constants can be defined within interfaces and records. In Java, Python, C# and C++ they are part of the
Constants can be defined within interfaces and records. In Java and C++ they are part of the
generated class; and in Objective-C, constant names are globals with the name of the
interface/record prefixed. Example:

```
record_with_const = record +c +j +o +p +s {
record_with_const = record +c +j +o {
const const_value: i32 = 8;
}
```

will be `RecordWithConst::CONST_VALUE` in C++, `RecordWithConst.CONST_VALUE` in Java,
`RecordWithConst.CONST_VALUE` in Python, `RecordWithConst.ConstValue` in C#, and `RecordWithConstConstValue` in Objective-C.
and `RecordWithConstConstValue` in Objective-C.

## Comments

Expand All @@ -364,8 +349,7 @@ will be `RecordWithConst::CONST_VALUE` in C++, `RecordWithConst.CONST_VALUE` in
```

If comments are placed on top or inside a type definition, they will be converted to
Javadoc / Doxygen compatible comments in the generated Java, C++, Objective-C and C++/CLI interfaces, or a
Python docstring.
Javadoc / Doxygen compatible comments in the generated Java, C++, and Objective-C interfaces.

## Deprecation Comments

Expand Down
17 changes: 1 addition & 16 deletions docs/modularization.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ C++/Objective-C/Java/C# you can tell Djinni to generate a special YAML file as p
This file then contains all the information Djinni requires to include your types in a different project.
Instructing Djinni to create these YAML files is controlled by the [YAML generation parameters](cli-usage.md#yaml-generation).

!!! caution

External types defined in YAML are not yet supported for Python.

## YAML file structure

Expand Down Expand Up @@ -127,20 +125,7 @@ struct Record1
};
```

```cpp
// For C++ <-> C++/CLI
public ref class Record1 {
public:
// Record1 public properties
internal:
using CppType = ::mylib::Record1;
using CsType = Record1^;
static CppType ToCpp(CsType cs) { return /* your magic here */; }
static CsType FromCpp(const CppType& cs) { return /* your magic here */; }
private:
// Record1 properties' backing fields
}
```


For `interface` classes the `CppType` alias is expected to be a `std::shared_ptr<T>`.

Expand Down
13 changes: 0 additions & 13 deletions src/it/resources/cppcli_circular_dependent_interface.djinni

This file was deleted.

Loading
Loading