GlueGen v2.6.0-rc-20250706
GlueGen, Native Binding Generator for Java (public API).
|
<style> table, th, td { border: 1px solid black; } </style>
Disclaimer: This documented shall be synchronized with source code, especially the configuration options.
Please also consider reading GlueGen Manual for general usage and configuration options.
GlueGen is a compiler for function and data-structure declarations, generating Java and JNI C code offline at compile time and allows using native libraries within your Java application.
GlueGen also provides a comprehensive runtime library offering
GlueGen's compiler reads ANSI C header files and separate configuration files which provide control over many aspects of the glue code generation. GlueGen uses a complete ANSI C parser and an internal representation (IR) capable of representing all C types to represent the APIs for which it generates interfaces. It has the ability to perform significant transformations on the IR before glue code emission.
GlueGen can produce native foreign function bindings to Java™ as well as map native data structures to be fully accessible from Java™ including potential calls to embedded function pointer.
GlueGen supports registering Java™ callback methods to receive asynchronous and off-thread native toolkit events, where a generated native callback function dispatches the events to Java™.
GlueGen also supports producing an OO-Style API mapping like JOGL's incremental OpenGL Profile API levels.
GlueGen is capable to bind low-level APIs such as the Java™ Native Interface (JNI) and the AWT Native Interface (JAWT) back up to the Java programming language.
Further, GlueGen supports generating `JNI_OnLoad*(..)` for dynamic and static libraries, also resolving off-thread JNIEnv*
lookup.
GlueGen utilizes JCPP, migrated C preprocessor written in Java™.
GlueGen is used for the JogAmp projects JOAL, JOGL and JOCL.
GlueGen is part of the JogAmp project.
Gluegen has build-in types (terminal symbols) for:
type | java-bits | native-x32 | native-x64 | type | signed | origin |
---|---|---|---|---|---|---|
void | 0 | 0 | 0 | void | void | ANSI-C |
char | 8 | 8 | 8 | integer | any | ANSI-C |
short | 16 | 16 | 16 | integer | any | ANSI-C |
int | 32 | 32 | 32 | integer | any | ANSI-C |
long | 64 | 32 | **32**† | integer | any | ANSI-C - Windows |
long | 64 | 32 | 64 | integer | any | ANSI-C - Unix |
float | 32 | 32 | 32 | float | signed | ANSI-C |
double | 64 | 64 | 64 | double | signed | ANSI-C |
__int32 | 32 | 32 | 32 | integer | any | windows |
__int64 | 64 | 64 | 64 | integer | any | windows |
int8_t | 8 | 8 | 8 | integer | signed | stdint.h |
uint8_t | 8 | 8 | 8 | integer | unsigned | stdint.h |
int16_t | 16 | 16 | 16 | integer | signed | stdint.h |
uint16_t | 16 | 16 | 16 | integer | unsigned | stdint.h |
int32_t | 32 | 32 | 32 | integer | signed | stdint.h |
uint32_t | 32 | 32 | 32 | integer | unsigned | stdint.h |
int64_t | 64 | 64 | 64 | integer | signed | stdint.h |
uint64_t | 64 | 64 | 64 | integer | unsigned | stdint.h |
intptr_t | 64 | 32 | 64 | integer | signed | stdint.h |
uintptr_t | 64 | 32 | 64 | integer | unsigned | stdint.h |
ptrdiff_t | 64 | 32 | 64 | integer | signed | stddef.h |
size_t | 64 | 32 | 64 | integer | unsigned | stddef.h |
wchar_t | 32 | 32 | 32 | integer | signed | stddef.h |
Warning: Try to avoid unspecified bit sized types, especially long, since it differs on Unix and Windows!
Notes:
Pointer values itself are represented as long
values on the Java side while using the native pointer-size, e.g. 32-bit or 64-bit, on the native end.
They may simply be accessible via long
or long[]
primitives in Java, or are exposed via com.jogamp.common.nio.PointerBuffer
.
See Struct Pointer-Pointer Support below.
Function return values are currently mapped from char*
to Java String using UTF-8 via JNI function
jstring NewStringUTF(JNIEnv *env, const char *bytes)
FIXME: This might need more flexibility in case UTF-8 is not suitable for 8-bit wide char
mappings or wide characters, e.g. for UTF-16 needs to be supported.
Function argument values are either mapped from char*
to Java String using UTF-8 via JNI function
const char * GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
.
Alternatively, if a 16-bit wide character type has been detected, i.e. short, the native character are mapped to Java using UTF-16 via JNI function
void GetStringRegion(JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf)
.
String value mapping for Struct
fields is performed solely from the Java side using Charset and is hence most flexible.
By default, UTF-8 is being used for getter and setter of String values.
The Struct class provides two methods to get and set the used Charset for conversion
In case the String length has not been configured via ReturnedArrayLength
, it will be dynamically calculated via strnlen(aptr, max_len)
.
The maximum length default for the strnlen(..)
operation is 8192 bytes and can be get and set using:
FIXME: This only works reliable using an 8-bit Charset encoding, e.g. the default UTF-8.
In general, depending on CPU and it's configuration (OS), alignment is set up for each type (char, short, int, long, ..).
Compounds (structures) are aligned naturally, i.e. their inner components are aligned
and are itself aligned to it's largest element.
See:
Modulo operation, where the 2nd handles the case offset == alignment:
padding = ( alignment - ( offset % alignment ) ) % alignment ;
aligned_offset = offset + padding ;
Optimization utilizing alignment as a multiple of 2 -> x % 2n == x & ( 2n - 1 )
remainder = offset & ( alignment - 1 ) ;
padding = ( remainder > 0 ) ? alignment - remainder : 0 ;
aligned_offset = offset + padding ;
Without branching, using the 2nd modulo operation for the case offset == alignment:
padding = ( alignment - ( offset & ( alignment - 1 ) ) ) & ( alignment - 1 ) ;
aligned_offset = offset + padding ;
See com.jogamp.gluegen.cgram.types.SizeThunk.align(..)
.
Runtime query is implemented as follows:
type | size 32 bit | alignment 32 bit | size 64 bit | alignment 64 bit |
---|---|---|---|---|
char | 1 | 1 | 1 | 1 |
short | 2 | 2 | 2 | 2 |
int | 4 | 4 | 4 | 4 |
float | 4 | 4 | 4 | 4 |
long | 4 | 4 | 8†,4∗ | 8†,4∗ |
pointer | 4 | 4 | 8 | 8 |
long long | 8 | 4†,8∗+ | 8 | 8 |
double | 8 | 4†,8∗+ | 8 | 8 |
long double | 12†∗,8+,16- | 4†∗,8+,16- | 16 | 16 |
† Linux, Darwin
+armv7l-eabi
- MacOsX-32bit-gcc4
∗ Windows
GlueGen supports producing an OO-Style API mapping like JOGL's incremental OpenGL Profile API levels.
ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/com/jogamp/opengl/GL.java
Ignore all extended interface symbols from named Java source file.
The named Java source file is parsed and a list of its symbols extracted, allowing GlueGen to ignore these in the generated interface (here GLES3).
This complements Extends
setting, see below.
Extends GLES3 GLES2
The generated interface GLES3 extends interface GLES2.
This complements ExtendedInterfaceSymbolsIgnore
setting, see above.
Implements GLES3Impl GLES3
The generated implementation GLES3Impl implements interface GLES3.
Example snippet from JOGL's GLES3 interface config gl-if-es3.cfg
Example snippet from JOGL's GLES3Impl implementation gl-es3-impl.cfg
Above produces the GLES3 interface and its implementation as visible in JOGL's UML document about OpenGL Profiles.
A Struct is a C compound type declaration, which can be mapped to a Java class.
A Struct may utilize the following data types for its fields
A field may be a direct aggregation, i.e. instance, within the struct including an array or a reference to a single element or array via a pointer.
Both, primitive, struct and pointer field type mappings only produce pure Java code, utilizing the GlueGen Runtime. Hence no additional native code must be compiled nor a resulting additional library loaded to use the mapping.
Only when mapping function-pointer within structs, additional native glue-code is produced to call the underlying native function which has to be compiled and its library loaded.
The generated method public static boolean usesNativeCode()
can be used to validate whether the produced Java class requires a corresponding library for additional native code.
long
values from the Java side void*
, within a struct are handled as `Opaque` configured pointer-types.setVal(..)
and releaseVal()
with care.releaseVal()
can be used.See also Opaque section in manual.
Opaque long T2_UndefStruct*
Pointers to T2_UndefStruct
will be handled opaque, i.e. as long
values from the Java side while maintaining their architecture dependent pointer size within native memory.
Immutable access can be set for a whole struct or a single field of a struct.
Immutable access will simply suppress generating setters in the Java code and hence also reduces the footprint of the generated Java class for such struct.
ImmutableAccess TK_Struct
Immutable access for the whole struct `TK_Struct
Sets pseudo-code flag ImmutableAccess, see below.
ImmutableAccess TK_Struct.val
Immutable access for the single field val
within struct TK_Struct
Sets pseudo-code flag ImmutableAccess, see below.
MaxOneElement TK_Struct.val
Sets field pointer val
to point to a array with a maximum of one element and unset initial value (zero elements).
Sets pseudo-code flag MaxOneElement, see below.
ReturnedArrayLength TK_Struct.val 3
Sets field pointer val
to point to a array with three elements.
Sets pseudo-code flag ConstElemCount, see below.
Having set ConstElemCount also implies native ownership for a Pointer referenced native memory.
ReturnedArrayLength TK_Struct.val 1
Sets field pointer val
to point to a array with one element.
Sets pseudo-code flags ConstElemCount and MaxOneElement, see below.
Having set ConstElemCount also implies native ownership for a Pointer referenced native memory.
ReturnedArrayLength TK_Struct.val getValElements()
Sets field pointer val
to point to a array with a variable length as described by the field valElements
retrievable via its getter getValElements()
.
Sets pseudo-code flag VariaElemCount, see below.
A direct C code char
array or indirect array via pointer can be interpreted as a Java String
.
ReturnsString TK_Struct.name
Sets field char-array or char-pointer name
to be additionally interpreted as a Java String
. Besides the byte[]
and ByteBuffer
getter and setter variants, a String
variant will be added.
Sets pseudo-code flags String, see below.
See *String Mapping* above.
ReturnsStringOnly TK_Struct.name
Sets field char-array or char-pointer name
to be exclusively interpreted as a Java String
. Instead of the byte[]
and ByteBuffer
getter and setter variants, a String
variant will be produced.
Sets pseudo-code flags StringOnly, see below.
See *String Mapping* above.
In general we have the following few cases
int32_t val[10]
val
within range, keeping memoryconst int32_t val[10]
int32_t* val
const int32_t* val
int32_t* val
val
within range, keeping memory owned by native codeconst int32_t* val
Please find below signature table as generated by the C Declaration including its C Modifier, e.g. const
for constant, [const]
for const and non-const and empty
for non-const (variable).
Further, the GlueGen Setting (see above) impacts the code generation as well.
Below table demonstrates primitive types being mapped within a struct
named TK_Struct
. A similar mapping is produced for struct
types, i.e. compounds.
C Mod | C Declaration | Java Setter | Java Getter | GlueGen Setting | Ownership | Remarks |
---|---|---|---|---|---|---|
static boolean usesNativeCode() | Java, static, true if using native code | |||||
static int size() | Java, static, native size in bytes | |||||
static TK_Struct create() | Java, static ctor | |||||
static TK_Struct create(ByteBuffer) | Java, static ctor w/ existing ByteBuffer | |||||
static TK_Struct derefPointer(long addr) | Java, static ctor dereferencing ByteBuffer at native address of size() | |||||
ByteBuffer getBuffer() | Java, underlying ByteBuffer | |||||
long getDirectBufferAddress() | Java, native address of underlying getBuffer() | |||||
int32_t val | setVal(int v) | int getVal() | Parent | |||
const | int32_t val | none | int getVal() | Parent | Read only | |
int32_t val | none | int getVal() | ImmutableAccess | Parent | Read only | |
[const] | int32_t* val | setVal(int v) [1][2] releaseVal() | int getVal() boolean isValNull() int getValElemCount() | MaxOneElement | Java | Starts w/ null elements, max 1 element |
const | int32_t* val | none | int getVal() boolean isValNull() static int getValElemCount() | ReturnedArrayLength 1 | Native | Const element count 1 |
| | int32_t* val | setVal(int v) | int getVal()
boolean isValNull()
static int getValElemCount() | ReturnedArrayLength 1 | Native | Const element count 1 | | | | int32_t val[3]| setVal(int[] src, int srcPos, int destPos, int len) [3] | IntBuffer getVal()
int[] getVal(int srcPos, int[] dest, int destPos, int len) | | Parent | Reuses parent memory,
fixed size. | | const | int32_t val[3]| none | IntBuffer getVal()
int[] getVal(int srcPos, int[] dest, int destPos, int len) | | Parent | Read only | | const | int32_t* val | none | IntBuffer getVal()
int[] getVal(int srcPos, int[] dest, int destPos, int len)
boolean isValNull()
static int getValElemCount() | ReturnedArrayLength 3 | Native | Read only
Const element count 3 | | | int32_t* val | setVal(int[] src, int srcPos, int destPos, int len) [4] | IntBuffer getVal()
int[] getVal(int srcPos, int[] dest, int destPos, int len)
boolean isValNull()
static int getValElemCount() | ReturnedArrayLength 3 | Native | Const element count 3.
Reuses native memory,
fixed size. | | | int32_t* val | setVal(boolean subset, int[] src, int srcPos, int destPos, int len) [5]
releaseVal() | IntBuffer getVal()
int[] getVal(int srcPos, int[] dest, int destPos, int len)
boolean isValNull()
int getValElemCount() | | Java | Starts w/ null elements.
Reuses or replaces Java memory,
variable size. | | const | int32_t* val | setVal(int[] src, int srcPos, int len) [6]
releaseVal() | IntBuffer getVal()
int[] getVal(int srcPos, int[] dest, int destPos, int len)
boolean isValNull()
int getValElemCount() | | Java | Starts w/ null elements.
Replaces Java memory,
variable size. | | | int32_t* val | setVal(boolean subset, int[] src, int srcPos, int destPos, int len) [7]
releaseVal() | IntBuffer getVal()
int[] getVal(int srcPos, int[] dest, int destPos, int len)
boolean isValNull() | ReturnedArrayLength getValCount() | Ambiguous | Variable element count
using field valCount,
which has getter and setter | | const | int32_t* val | setVal(int[] src, int srcPos, int len) [8]
releaseVal() | IntBuffer getVal()
int[] getVal(int srcPos, int[] dest, int destPos, int len)
boolean isValNull() | ReturnedArrayLength getValCount() | Ambiguous | Variable element count
using field valCount,
which has getter and setter | | [const] | char* name | setName(String srcVal)
releaseVal() | String getName()
boolean isNameNull()
int getNameElemCount() | ReturnsStringOnly | Java | String only, w/ EOS | | [const] | char* name | setName(String srcVal)
setName(byte[] src, int srcPos, int destPos, int len)
releaseVal() | String getNameAsString()
ByteBuffer getName()
boolean isNameNull()
int getNameElemCount() | ReturnsString | Java | String and byte access, w/ EOS|
void com.jogamp.gluegen.test.junit.generation.TK_Field.setVariaInt32PointerMaxOneElemElemCount(int src)
Setter for native field variaInt32PointerMaxOneElem, referencing a Java owned array with variable element count of 0 initial elements.
Maximum element count is 1.
Native Signature:
Will reuse memory if existing, otherwise allocating memory.
TK_Field com.jogamp.gluegen.test.junit.generation.TK_Field.setConstInt32PointerMaxOneElem(int src)
Setter for native field variaInt32PointerMaxOneElem, referencing a Java owned array with variable element count of 0 initial elements.
Maximum element count is 1.
Native Signature:
Always replaces memory due to const
value modifier.
TK_Field com.jogamp.gluegen.test.junit.generation.TK_Field.setVariaInt32ArrayConstLen(int[] src, int srcPos, int destPos, int length)
Setter for native field variaInt32ArrayConstLen, being an array with fixed element count of 3 elements.
Native Field Signature (ArrayType) 'int32_t *', size [fixed false, lnx64 12], const[false], array*1
Copies the given source elements into the respective field's existing memory.
Parameters:
&&
srcPos + length <= src.length, otherwise an IndexOutOfBoundsException is thrown
destPos starting element position within the destination with 'destPos >= 0
&& destPos + length <= elemCount
, otherwise an exception is thrown&&
srcPos + length <= src.length&&
destPos + length <= elemCount`, otherwise an IndexOutOfBoundsException is thrownReturns:
TK_Field com.jogamp.gluegen.test.junit.generation.TK_Field.setVariaInt32PointerConstLen(int[] src, int srcPos, int destPos, int length)
Setter for native field variaInt32PointerConstLen, referencing a natively owned array with fixed element count of 3 elements.
Native Signature:
Copies the given source elements into the respective field's existing memory.
Parameters:
&&
srcPos + length <= src.length, otherwise an IndexOutOfBoundsException is thrown
destPos starting element position within the destination with 'destPos >= 0
&& destPos + length <= elemCount
, otherwise an exception is thrown&&
srcPos + length <= src.length&&
destPos + length <= elemCount`, otherwise an IndexOutOfBoundsException is thrownReturns:
TK_Field com.jogamp.gluegen.test.junit.generation.TK_Field.setVariaInt32PointerVariaLen(boolean subset, int[] src, int srcPos, int destPos, int length)
Setter for native field variaInt32PointerVariaLen, referencing a Java owned array with variable element count of 0 initial elements.
Native Signature:
Copies the given source elements into the respective field, either writing into the existing memory or creating a new memory and referencing it.
Parameters:
true
keeps the underlying memory and only allows to set up to elemCount
elements. Otherwise may replace the underlying memory if destPos + length != elemCount
.&&
srcPos + length <= src.length, otherwise an IndexOutOfBoundsException is thrown
destPos starting element position within the destination with 'destPos >= 0
. If subset == true
, destPos + length <= elemCount
also must be be true
. Otherwise an exception is thrown&&
srcPos + length <= src.length`, otherwise an IndexOutOfBoundsException is thrownReturns:
TK_Field com.jogamp.gluegen.test.junit.generation.TK_Field.setConstInt32PointerVariaLen(int[] src, int srcPos, int length)
Setter for native field constInt32PointerVariaLen, referencing a Java owned array with variable element count of 0 initial elements.
Native Signature:
Replaces the respective field's memory with a new memory segment containing given source elements and referencing it.
Parameters:
&&
srcPos + length <= src.length, otherwise an IndexOutOfBoundsException is thrown
length the element count to be copied with 'length >= 0
&& srcPos + length <= src.length
, otherwise an IndexOutOfBoundsException is thrownReturns:
TK_Field com.jogamp.gluegen.test.junit.generation.TK_Field.setVariaInt32PointerCustomLen(boolean subset, int[] src, int srcPos, int destPos, int length)
Setter for native field variaInt32PointerCustomLen, referencing a mixed and ambigously owned (warning) array with variable element count of getVariaInt32PointerCustomLenElemCount() elements.
Native Signature:
Copies the given source elements into the respective field, either writing into the existing memory or creating a new memory and referencing it.
Parameters:
true
keeps the underlying memory and only allows to set up to elemCount
elements. Otherwise may replace the underlying memory if destPos + length != elemCount
.&&
srcPos + length <= src.length, otherwise an IndexOutOfBoundsException is thrown
destPos starting element position within the destination with 'destPos >= 0
. If subset == true
, destPos + length <= elemCount
also must be be true
. Otherwise an exception is thrown&&
srcPos + length <= src.length`, otherwise an IndexOutOfBoundsException is thrownReturns:
TK_Field com.jogamp.gluegen.test.junit.generation.TK_Field.setConstInt32PointerCustomLen(int[] src, int srcPos, int length)
Setter for native field constIntxxPointerCustomLen, referencing a mixed and ambigously owned (warning) array with variable element count of getConstIntxxPointerCustomLenElemCount() elements.
Native Signature:
Replaces the respective field's memory with a new memory segment containing given source elements and referencing it.
Parameters:
&&
srcPos + length <= src.length, otherwise an IndexOutOfBoundsException is thrown
length the element count to be copied with 'length >= 0
&& srcPos + length <= src.length
, otherwise an IndexOutOfBoundsException is thrownReturns:
See primitive *Pointer Mapping* above.
Pointer are exposed in the following examples
or via and undefined forward-declared struct
and the following GlueGen configuration
TODO: Enhance documentation
GlueGen supports function pointers as struct fields,
generating function calls as methods as well function-pointer opaque getter and setter as long
types.
The latter only in case if mutable, i.e. non-const.
Assume the following C Header file example:
and the following GlueGen configuration
This will lead to the following result for const T2_CustomFuncA customFuncA1
and similar to T2_CustomFuncB customFuncB1
GlueGen supports registering Java callback methods to receive asynchronous and off-thread native toolkit events, where a generated native callback function dispatches the events to Java.
Implementation generates a static Java callback dispatcher for each defined SetCallbackFunction
, which gets invoked by the generated native static counterpart with all arguments required.
The static callback utilizes its own synchronization for thread-safety and fetches the required data set stored at SetCallbackFunction
to dispatch the call to the users' CallbackFunction
.
In case the callback has been removed already, the static callback simply bails out quietly.
The native code does not create, release or manage heap memory and therefore is considered safe.
Usually the same UserParam
type is used in both items (or hooks), SetCallbackFunctionName
and CallbackFunctionType
, which we call a homogeneous UserParam
mapping.
Even in a homogeneous UserParam
mapping, handling of the UserParam
value might differ in the native binding code.
To specify a non homogeneous UserParam
mapping, i.e. heterogeneous UserParam
mapping, the UserParam
index of the SetCallbackFunction
must be set in the configuration.
The following mappings are supported.
A pure Java Object type is used for both, SetCallbackFunctionName
and CallbackFunctionType
.
It's a homogeneous UserParam
mapping, where the native side receives a simple unique ID and shall not dereference the pointer.
The static Java callback dispatcher fetches the Java UserParam
Object from the key-mapped data value.
Instead of using the default plain Java Object
type, a custom *UserParamClass* can be specified in the configuration, which is recommended for more clarity in the resulting API.
A GlueGen generated *Struct type* is used for both, SetCallbackFunctionName
and CallbackFunctionType
.
It's a homogeneous UserParam
mapping, where the native side receives the actual native struct address.
The static Java callback dispatcher dereferences the received native struct address (long), i.e. rebuilding the struct Object to be passed to the users' CallbackFunction
.
An anonymous pointer (long) for SetCallbackFunctionName
and a GlueGen generated *struct type* for CallbackFunctionType
is being used.
It's a heterogeneous UserParam
mapping, where the toolkit is expected to place the given anonymous pointer inside the defined struct type passed to the CallbackFunction
.
The SetCallback-UserParamIndex
for the different parameter-type is set in the configuration.
The static Java callback dispatcher dereferences the received native struct address (long), i.e. rebuilding the struct Object to be passed to the users' CallbackFunction
.
Configuration directives are as follows:
JavaCallbackDef <SetCallbackFunctionName> <SetCallback-UserParamIndex> <CallbackFunctionType> <CallbackFunction-UserParamIndex> [<Callback-UserParamClass> [<Callback-KeyClass>]] JavaCallbackKey <SetCallbackFunctionName> <SetCallback-ParamIndex>* <CallbackFunctionType> <CallbackFunction-ParamIndex>*
JavaCallbackDef
and JavaCallbackKey
use the name of the SetCallbackFunction
as its first attribute, as it is core to the semantic mapping of all resources. They also have to use the same CallbackFunctionType
.
JavaCallbackDef
attributes:
SetCallbackFunction
: SetCallbackFunction
name of the native toolkit API responsible to set the callbackSetCallback-UserParamIndex
: UserParam
parameter-index of the SetCallbackFunction
or <0
to disable UserParam
CallbackFunctionType
: The native toolkit API typedef-name of the function-pointer-type, aka the callback type nameCallbackFunction-UserParamIndex
: The userParam
parameter-index of the CallbackFunctionType
, which allows to indicate a heterogeneous `UserParam` or <0
to disable UserParam
Callback-UserParamClass
: Optional custom *UserParamClass* overriding the default Object
for non-compound UserParam
types.Callback-KeyClass
: Optional custom *KeyClass*, providing the hash-map-key.The SetCallbackFunction
is utilized to set the CallbackFunction
as well as to remove it passing null
for the CallbackFunction
.
If mapping the CallbackFunction
to keys, the user must specify the same key arguments when setting and removing the CallbackFunction
.
If no keys are defined via JavaCallbackKey
or not manually injected using a custom Callback-KeyClass
, see below, the CallbackFunction
has global scope.
In case keys are defined via JavaCallbackKey
and no manually injected custom Callback-KeyClass
used, a public Callback-KeyClass
is being generated covering the defined keys.
Keys allow to limit the scope, i.e. map multiple CallbackFunction
to the different keys.
To remove a previously set CallbackFunction
via SetCallbackFunction
, the key arguments must match.
JavaCallbackKey
attributes
SetCallbackFunction
: SetCallbackFunction
name of the native toolkit API responsible to set the callbackSetCallback-ParamIndex
: List of parameter indices of the SetCallbackFunction
, denoting the key(s) limiting the callback scope, i.e. the callback and all resources will be mapped to this key. The optional Callback-KeyClass
may override this semantic.CallbackFunctionType
: The native toolkit API typedef-name of the function-pointer-type, the same callback type name as defined in JavaCallbackDef
CallbackFunction-ParamIndex
: List of parameter indices of the CallbackFunctionType
, matching the semantic parameter of SetCallback-ParamIndex
.Instead of using the default plain Java Object
for non-compound UserParam
types, a custom Callback-UserParamClass
can be specified in the configuration, which produces more clarity in the resulting API.
The Callback-KeyClass
is the optional user-written hash-map-key definition and shall handle all key parameter of the SetCallbackFunction
as defined via JavaCallbackKey
, see above.
Callback-KeyClass
may be used to add external key-components, e.g. current-thread or a toolkit dependent context.
The Callback-KeyClass
shall implement the following hash-map-key standard methods
boolean equals(Object)
int hashCode()
Callback-KeyClassName(...)
constructor receiving all key parameter of SetCallbackFunction
as defined via JavaCallbackKey
, see above.Note that `LibraryOnLoad <LibraryBasename>` must be specified in exactly one native code-unit within one native library.
It provides code to allow the generated native callback-function to attach the current thread to the JavaVM*
, retrieving a valid JNIEnv*
, see `LibraryOnLoad <LibraryBasename>` for details.
The public CallbackFunction
interface is generated.
The default public Callback-KeyClass
is generated if keys are used and no custom class is specified, see above.
The public toolkit API SetCallbackFunction
method is being generated.
Additional public maintenance methods are generated. In case keys are being used, they expect Callback-KeyClass
as an argument, otherwise they expect no argument for global scope.
In case a Callback-KeyClass
is used, the additional maintenance methods are:
Callback-KeyClass
> getSetCallbackFunctionName
Keys()*SetCallbackFunctionName
Mapped(Callback-KeyClass
)* queries whether SetCallbackFunctionName
is mapped to key.CallbackFunction
getSetCallbackFunctionName
(Callback-KeyClass
)* returns the mapped CallbackFunction
, null if not mappedCallback-UserParamClass
getSetCallbackFunctionName
UserParam(Callback-KeyClass
)* returns the mapped userParam
object, null if not mappedSetCallbackFunctionName
(Callback-KeyClass
)* releases the mapped CallbackFunction
data set associated via SetCallbackFunctionName
.SetCallbackFunctionName
() releases complete mapped CallbackFunction
data set associated via SetCallbackFunctionName
.If no Callback-KeyClass
is used, the additional maintenance methods are:
SetCallbackFunctionName
Mapped() queries whether SetCallbackFunctionName
is mapped.CallbackFunction
getSetCallbackFunctionName
()* returns the mapped CallbackFunction
, null if not mappedCallback-UserParamClass
getSetCallbackFunctionName
UserParam()* returns the mapped userParam
object, null if not mappedSetCallbackFunctionName
() releases the mapped CallbackFunction
data set associated via SetCallbackFunctionName
.Note that the releaseSetCallbackFunctionName
(*) and releaseAllSetCallbackFunctionName
() methods are not the proper toolkit API way to remove the callback, try to use original SetCallbackFunctionName
API method instead using a null
CallbackFunction
reference.
Please consider the following currently enabled constraints using JavaCallback
T2_CallbackFunc01
(see above)to
byte[]and
Stringmapping etc.
The native callback function can only return no-value, i.e.
void, or a primitive type. Usually
void` is being used in toolkit APIs.CMethodBindingEmitter.emitBodyMapCToJNIType(..)
.SetCallbackFunction
must be called with null
for the CallbackFunction
argument but with the same *key arguments* (see `JavaCallbackKey`) as previously called to set the callback.SetCallbackFunction
, all maintenance methods and the native callback dispatcher are thread-safe
This example demonstrates a homogeneous *Java Object* `UserParam` mapping with a globally scoped CallbackFunction
and UserParam
.
The callback T2_CallbackFunc01
has global scope, i.e. is not mapped to any key and can be only set globally.
C-API header snippet:
and the following GlueGen configuration
Note that `LibraryOnLoad Bindingtest2` must be specified in exactly one native code-unit within the library. It provides code to allow the generated native callback-function to attach the current thread to the JavaVM*
generating a new JNIEnv*
in daemon mode - or just to retrieve the thread's JNIEnv*
, if already attached to the JavaVM*
.
This will lead to the following interface
This example demonstrates a homogeneous *Java Object* `UserParam` mapping with a key-mapped CallbackFunction
and UserParam
.
Additionally a custom *UserParamClass* ALCcontext
is being used for more clarity in the resulting API.
This example is derived from OpenAL's AL_SOFT_callback_buffer
extension.
The callback ALBUFFERCALLBACKTYPESOFT
is mapped to buffer
name, i.e. one callback can be set for each buffer.
C-API Header snipped
and the following GlueGen configuration
leading to the following interface
Similar example as example 2a, but using a custom *KeyClass* to map CallbackFunction
and UserParam
and also accommodating a different key-parameter order between SetCallbackFunction
and CallbackFunction
.
C-API Header snipped
GlueGen configuration snippet with the added option attribute for the Callback-KeyClass
in directive JavaCallbackDef
.
Implementation utilizes a custom Callback-KeyClass
implementation for void alBufferCallback1(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, ALCcontext userptr)
, which uses one key, i.e. buffer
.
Similar example as example 2a, but having the UserParam
as part of the 2 component-key and defining Callback-UserParamClass
class as ALCcontext
.
C-API Header snipped
GlueGen configuration snippet with the added option attribute for the Callback-UserParamClass
in directive JavaCallbackDef
.
Resulting to the default KeyClass
This example demonstrates a homogeneous *Struct* `UserParam` mapping with a key-mapped CallbackFunction
and UserParam
.
The callback T2_CallbackFunc11
is passed by the toolkit to the CallbackFunction
and by the user to the registration method MessageCallback11b(..)
.
C-API Header snipped
and the following GlueGen configuration
leading to the following interface
This example demonstrates a heterogeneous *Struct* `UserParam` mapping with a key-mapped CallbackFunction
and UserParam
.
The callback T2_CallbackFunc11
is managed by the toolkit and passed to the callback function, while user passes a void*
as a long
value to the registration method MessageCallback11b(..)
. The toolkit associates the users' void*
pointer with the T2_CallbackFunc11
.
C-API Header snipped
and the following GlueGen configuration
leading to the following interface
This example demonstrates a JavaCallBack without user param and only a global key.
The callback T2_CallbackFunc12
is managed by the toolkit and passed to the callback function, while user passes JavaCallback to the registration method SetLogCallBack(..)
.
C-API Header snipped
and the following GlueGen configuration
leading to the following interface
TODO: Enhance documentation
LibraryOnLoad <LibraryBasename>
can be specified in one native code-unit within one native library maximum, otherwise multiple function definitions would occur.
In case Java™ callback methods are used, it is required to have LibraryOnLoad <LibraryBasename>
specified in exactly one native code-unit within one native library.
LibraryOnLoad <LibraryBasename>
generates native JNI code to handle the JavaVM*
instance
JavaVM* JVMUtil_GetJavaVM()
returning the static JavaVM*
instance for LibraryBasename
set by JNI_OnLoad*()
JNI_OnLoad(..)
setting the static JavaVM*
instance for LibraryBasename
, used for dynamic libraries,JNI_OnLoad_<LibraryBasename>(..)
setting the static JavaVM*
instance for LibraryBasename
, used for static libraries,Further the following functions are produced to attach and detach the current thread to and from the JVM, getting and releasing the JNIEnv*
JNIEnv* JVMUtil_GetJNIEnv(int asDaemon, int* jvmAttached)
returns the JNIEnv*
with current thread being newly attached to the JavaVM*
if result *jvmAttached == true
, otherwise the current thread was already attached to the JavaVM*
void JVMUtil_ReleaseJNIEnv(JNIEnv* env, int detachJVM)
releases the JNIEnv*
, i.e. detaching the current thread from the JavaVM*
if detachJVM == true
, otherwise funtion does nothing.
GlueGen provides convenient platform headers,
which can be included in your C header files for native compilation and GlueGen code generation.
Example:
To compile this file you have to include the following folder to your compilers system includes, ie -I
:
To generate code for this file you have to include the following folder to your GlueGen includeRefid
element:
To identity a GlueGen code generation run, GlueGen defines the following macros: