Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
djinni
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
djinni
Commits
b704a7c3
Commit
b704a7c3
authored
Jul 13, 2015
by
Miro Knejp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
YAML file documentation
parent
4caf5c6e
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
206 additions
and
0 deletions
+206
-0
README.md
README.md
+135
-0
example/example.yaml
example/example.yaml
+71
-0
No files found.
README.md
View file @
b704a7c3
...
...
@@ -245,6 +245,141 @@ interface/record prefixed. Example:
will be
`RecordWithConst::CONST_VALUE`
in C++,
`RecordWithConst.CONST_VALUE`
in Java, and
`RecordWithConstConstValue`
in Objective-C.
## Modularization and Library Support
When generating the interface for your project and wish to make it available to other users
in all of C++/Objective-C/Java you can tell Djinni to generate a special YAML file as part
of the code generation process. 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 follwoing arguments:
-
`--yaml-out`
: The output folder for YAML files (Generator disabled if unspecified).
-
`--yaml-out-file`
: If specified all types are merged into a single YAML file instead of generating one file per type (relative to
`--yaml-out`
).
-
`--yaml-prefix`
: The prefix to add to type names stored in YAML files (default:
`""`
).
Such a YAML file looks as follows:
```yml
---
name: mylib_record1
typedef: 'record +c deriving(eq, ord)'
params: []
prefix: 'mylib'
cpp:
typename: '::mylib::Record1'
header: '"MyLib/Record1.hpp"'
byValue: false
objc:
typename: 'MLBRecord1'
header: '"MLB/MLBRecord1.h"'
boxed: 'MLBRecord1'
pointer: true
hash: '%s.hash'
objcpp:
translator: '::mylib::djinni::objc::Record1'
header: '"mylib/djinni/objc/Record1.hpp"'
java:
typename: 'com.example.mylib.Record1'
boxed: 'com.example.mylib.Record1'
reference: true
generic: true
hash: '%s.hashCode()'
jni:
translator: '::mylib::djinni::jni::Record1'
header: '"Duration-jni.hpp"'
typename: jobject
typeSignature: 'Lcom/example/mylib/Record1;'
---
name: mylib_interface1
typedef: 'interface +j +o'
(...)
---
name: mylib_enum1
typedef: 'enum'
(...)
```
Each document in the YAML file describes one extern type.
A full documentation of all fields is available in `example/example.yaml`. You can also check
the files `test-suite/djinni/date.yaml` and `test-suite/djinni/duration.yaml` for some
real working examples of what you can do with it.
To use a library type in your project simply include it in your IDL file and refer to it using
its name identifier:
```
@extern "mylib.yaml"
client_interface = interface +c {
foo(): mylib_record1;
}
```
These files can be created by hand as long as you follow the required format. This allows you
to support types not generated by Djinni. See `test-suite/djinni/duration.yaml` and the
accompanying translators in `test-suite/handwritten-src/cpp/Duration-objc.hpp` and
`test-suite/handwritten-src/cpp/Duration-jni.hpp` for an advanced example. Handwritten
translators implement the following concept:
```
cpp
// For C++
<->
Objective-C
struct Record1
{
using CppType = ::mylib::Record1;
using ObjcType = MLBRecord1
*
;
static CppType toCpp(ObjcType o) { return /* your magic here */; }
static ObjcType fromCpp(CppType c) { return /* your magic here */; }
// Option 1: use this if no boxing is required
using Boxed = Record1;
// Option 2: or this if you do need dedicated boxing behavior
struct Boxed
{
using ObjcType = MLBRecord1Special*;
static CppType toCpp(ObjcType o) { return /* your magic here */; }
static ObjcType fromCpp(CppType c) { return /* your magic here */; }
}
};
```
```cpp
// For C++ <-> JNI
#include "djinni_support.hpp"
struct Record1
{
using CppType = ::mylib::Record1;
using JniType = jobject;
static CppType toCpp(JniType j) { return /* your magic here */; }
// The return type *must* be LocalRef<T> if T is not a primitive!
static ::djinni::LocalRef<jobject> JniType fromCpp(CppType c) { return /* your magic here */; }
using Boxed = Record1;
};
```
For
`interface`
classes the
`CppType`
alias is expected to be a
`std::shared_ptr<T>`
.
Be sure to put the translators into representative and distinct namespaces.
If your type is generic the translator takes the same number of template parameters.
At usage each is instantiated with the translators of the respective type argument.
```
cpp
template
<
class
A
,
class
B
>
struct
Record1
{
using
CppType
=
::
mylib
::
Record1
<
typename
A
::
CppType
,
typename
B
::
CppType
>
;
using
ObjcType
=
MLBRecord1
*
;
static
CppType
toCpp
(
ObjcType
o
)
{
// Use A::toCpp() and B::toCpp() if necessary
return
/* your magic here */
;
}
static
ObjcType
fromCpp
(
CppType
c
)
{
// Use A::fromCpp() and B::fromCpp() if necessary
return
/* your magic here */
;
}
using
Boxed
=
Record1
;
};
```
## Miscellaneous
### Record constructors / initializers
Djinni does not permit custom constructors for records or interfaces, since there would be
...
...
example/example.yaml
0 → 100644
View file @
b704a7c3
# This is an example YAML file for being imported in other projects.
# It holds all necessary information for Djinni to integrate foreign types into the generated code.
# All fields are mandatory.
---
# The name to refer to this type in other .djinni files.
# It must be unique in the entire Djinni run, so you should pick a unique prefix for your framework/library.
name
:
mylib_record1
# Specifies what kind of type this is.
# Supports the same syntax as is used to declare types in .djinni files.
# Examples: 'interface +c', 'record deriving(eq, or)', 'enum', 'interface +j +o'
# This determines how Djinni integrates this type into function parameters, fields or return types and operators.
typedef
:
'
record
+c
deriving(eq,
ord)'
# The (potentially empty) list of required type parameters.
params
:
[
type_param1
,
type_param2
]
# This string is stripped from the value specified under "name" to ensure Djinni is referencing the correct typename in code.
# May be an empty string if you don't have a prefix (bad!)
prefix
:
'
mylib'
cpp
:
# The name of this type in C++ (without template arguments). Should be fully qualified.
typename
:
'
::mylib::Record1'
# The header required in C++ to use your type. Must include "" or <>.
header
:
'
"MyLib/Record1.hpp"'
# Only used for "record" types: determines whether it should be passed by-value in C++.
# If this is false it is always passed as const&
byValue
:
false
objc
:
# The name of this type in Objective-C.
typename
:
'
MLBRecord1'
# The header required in Objective-C to use your type.
header
:
'
"MLB/MLBRecord1.h"'
# Only used for "record" types: determines the type used when boxing the record is required.
# Should not contain the pointer asterisk "*", protocols are not supported.
# This fiels is the same as "typename" most of the time as records are typically NSObjects and require no special boxing.
# However, some may not, for example NSTimeInterval is boxed to NSNumber.
boxed
:
'
MLBRecord1'
# Specifies whether the unboxed type is a pointer.
pointer
:
true
# If the type is a "record" and has "eq" deriving then this string must not be empty.
# It declares a well-formed expression with a single "%s" format placeholder replaced with the variable for which the hash code is needed
hash
:
'
%s.hash'
objcpp
:
# The fully qualified name of the class containing the toCpp/fromCpp methods.
translator
:
'
::mylib::djinni::objc::Record1'
# Where to find the translator class.
header
:
'
"mylib/djinni/objc/Record1.hpp"'
java
:
# The name of the (fully qualified) Java type to be used.
typename
:
'
com.example.mylib.Record1'
# Only used for "record" types: determines the type used when boxing the record is required.
# This field is the same as "typename" most of the time as records are typically Objects and require no special boxing.
# However maybe your record has a dedicated boxed type and this field allows you to control that.
boxed
:
'
com.example.mylib.Record1'
# If this is true "typename" is an Object reference (and not a builtin).
reference
:
true
# Controls whether the type parameters as specified in "params" are forwarded as generics to Java.
# This is useful when templates are only used in C++ (e.g. std::chrono::duration<rep, period> versus java.time.Duration)
# This should be true by default (even if your type has no parameters) and only set to false if required
generic
:
true
# If the type is a "record" and has "eq" deriving then this string must not be empty.
# It declares a well-formed expression with a single "%s" format placeholder replaced with the variable for which the hash code is needed
hash
:
'
%s.hashCode()'
jni
:
# The fully qualified name of the class containing the toCpp/fromCpp methods.
translator
:
'
::mylib::djinni::jni::Record1'
# Where to find the translator class.
header
:
'
"mylib/djinni/jni/Record1.hpp"'
# The type used for representations in JNI (jobject, jint, jbyteArray, etc)
typename
:
jobject
# The mangled type signature of your type to be found by JNI.
# See the JNI docs for its format
typeSignature
:
'
Lcom/example/mylib/Record1;'
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment