# GlueGen Native Data & Function Mapping for Java™
*Disclaimer: This documented shall be synchronized with source code,
especially the configuration options.*
Please also consider reading [GlueGen Manual](manual/index.html) for details on native data and
function mappings.
## References
- [GlueGen Git Repo](https://jogamp.org/cgit/gluegen.git/about/)
- [GlueGen Java™ API-Doc](https://jogamp.org/deployment/jogamp-next/javadoc/gluegen/javadoc/)
- [GlueGen Manual](manual/index.html)
- [GlueGen Project Page](https://jogamp.org/gluegen/www/)
- [How To Build](HowToBuild.html)
## Overview
[GlueGen](https://jogamp.org/gluegen/www/) 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](https://jogamp.org/deployment/jogamp-next/javadoc/gluegen/javadoc/) offering
- Support for multi-arch and java code fat-jar deployment
- Native library including JNI bundle handling and Jar file cache
- Platform architecture information retrieval, ELF parser, alignment etc
- Enhanced NIO buffer handling for pointer, arrays, DMA mapping etc
- Network Uri RFC 2396, connection and resource handler to simplify asset loading
- Bitstream, hash maps, ringbuffer, sha cumulator, reflection and threading utils
- Abstract AudioFormat and AudioSink interfaces, concurrent locks .. and more
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](#struct-mapping) to be fully accessible from Java™ including
potential calls to [embedded function pointer](#struct-function-pointer-support).
GlueGen supports [registering Java™ callback methods](#java-callback)
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](#oo-style-api-interface-mapping) like [JOGL's incremental OpenGL Profile API levels](../../jogl/doc/uml/html/index.html).
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](#libraryonload-librarybasename-for-jni_onload-), also resolving off-thread `JNIEnv*` lookup.
GlueGen utilizes [JCPP](https://jogamp.org/cgit/jcpp.git/about/), migrated C preprocessor written in Java™.
GlueGen is used for the [JogAmp](https://jogamp.org) projects
[JOAL](https://jogamp.org/cgit/joal.git/about/),
[JOGL](https://jogamp.org/cgit/jogl.git/about/) and
[JOCL](https://jogamp.org/cgit/jocl.git/).
GlueGen is part of [the JogAmp project](https://jogamp.org).
## Primitive Mapping
Gluegen has build-in types (terminal symbols) for:
| type | java-bits | native-bits
* Native Field Signature
* Native Field Signature
* Native Field Signature
x32 | native bits
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:**
* † Type **long** will result in broken code on Windows, since we don't differentiate the OS and it's bit size is ambiguous.
* Anonymous void-pointer _void\*_ are mapped to NIO _Buffer_.
* Pointers to pointer-size types like _intptr\_t\*_, _uintptr\_t\*_, _ptrdiff\_t\*_ and _size\_t\*_ are mapped to _PointerBuffer_, to reflect the architecture depending storage size.
### Pointer Mapping
*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](#struct-pointer-pointer-support) below.
### String Mapping
#### Function return String values
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 String values
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)`.
#### Struct String mapping
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
```
/** Returns the Charset for this class's String mapping, default is StandardCharsets.UTF_8. */
public static Charset getCharset() { return _charset; };
/** Sets the Charset for this class's String mapping, default is StandardCharsets.UTF_8. */
public static void setCharset(Charset cs) { _charset = cs; }
```
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:
```
/** Returns the maximum number of bytes to read to determine native string length using `strnlen(..)`, default is 8192. */
public static int getMaxStrnlen() { return _max_strnlen; };
/** Sets the maximum number of bytes to read to determine native string length using `strnlen(..)`, default is 8192. */
public static void setMaxStrnlen(int v) { _max_strnlen = v; }
```
*FIXME*: This only works reliable using an 8-bit Charset encoding, e.g. the default *UTF-8*.
### Alignment for Compound Data
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:
* [Wikipedia Data Structure Alignment](http://en.wikipedia.org/wiki/Data_structure_alignment)
* [Wikipedia Data Structure Alignment - Padding](http://en.wikipedia.org/wiki/Data_structure_alignment#Data_structure_padding)
* [Viva64 Data Alignment](http://www.viva64.com/en/l/0021/)
* [Apple: Darwin 64bit Porting - Data Type Size & Alignment](http://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/64bitPorting/transition/transition.html#//apple_ref/doc/uid/TP40001064-CH207-SW1)
#### Simple alignment arithmetic
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(..)`.
#### Type Size & Alignment for x86, x86\_64, armv6l-32bit-eabi and Window(mingw/mingw64)
Runtime query is implemented as follows:
```
typedef struct {
char fill; // nibble one byte
// padding to align s1: padding_0
type_t s1; //
} test_struct_type_t;
padding_0 = sizeof(test_struct_type_t) - sizeof(type_t) - sizeof(char) ;
alignmentOf(type_t) = sizeof(test_struct_type_t) - sizeof(type_t) ;
```
| 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
## OO-Style API Interface Mapping
GlueGen supports producing an OO-Style API mapping like [JOGL's incremental OpenGL Profile API levels](../../jogl/doc/uml/html/index.html).
### OO-Style Mapping Settings
* `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.
### OO-Style Example
Example snippet from JOGL's GLES3 interface config `gl-if-es3.cfg`
```
...
ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/com/jogamp/opengl/GL.java
ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/com/jogamp/opengl/GL2ES2.java
ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/com/jogamp/opengl/GLES2.java
ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/com/jogamp/opengl/GL2ES3.java
ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/com/jogamp/opengl/GL3ES3.java
ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/com/jogamp/opengl/GL4ES3.java
ExtendedInterfaceSymbolsIgnore ../src/jogl/classes/com/jogamp/opengl/GLBase.java
Package com.jogamp.opengl
Style InterfaceOnly
JavaClass GLES3
Extends GLES3 GLES2
Extends GLES3 GL4ES3
...
```
Example snippet from JOGL's GLES3Impl implementation `gl-es3-impl.cfg`
```
...
ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/com/jogamp/opengl/GL.java
ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/com/jogamp/opengl/GL2ES2.java
ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/com/jogamp/opengl/GLES2.java
ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/com/jogamp/opengl/GL2ES3.java
ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/com/jogamp/opengl/GL3ES3.java
ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/com/jogamp/opengl/GL4ES3.java
ExtendedInterfaceSymbolsIgnore ../build-temp/gensrc/classes/com/jogamp/opengl/GLES3.java
ExtendedInterfaceSymbolsIgnore ../src/jogl/classes/com/jogamp/opengl/GLBase.java
Style ImplOnly
ImplPackage jogamp.opengl.es3
ImplJavaClass GLES3Impl
Implements GLES3Impl GLES2
Implements GLES3Impl GLES3
...
```
Above produces the GLES3 interface and its implementation as visible in JOGL's UML document [about OpenGL Profiles](../../jogl/doc/uml/html/index.html).
## Struct Mapping
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
* *Primitive*, i.e. *char*, *int32_t*, ...
* See [*Primitive Mapping*](#primitive-mapping) above.
* See [*Opaque and `void*` notes*](#struct-mapping-notes) below.
* See [*Pointer Mapping*](#pointer-mapping) for *pointer-to-pointer* values above and [Struct Pointer-Pointer Support](#struct-pointer-pointer-support) below.
* See [*String Mapping*](#string-mapping) above.
* *Struct*, i.e. an aggregated or referenced compound variable
* *Function Pointer*, a *typedef*'ed and set callable function pointer, see [Struct Function-Pointer Support](#struct-function-pointer-support) below.
* *Java Callback from Native Code*, see [section below](#java-callback)
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.
### Struct Mapping Notes
* [`Opaque` configured pointer-types](#opaque-java-primitive-type-symbol) are treated as `long` values from the Java side
while maintaining their architecture dependent pointer size within native memory.
* Void pointers, i.e. `void*`, within a struct are handled as [`Opaque` configured pointer-types](#opaque-java-primitive-type-symbol).
* *ConstElemCount* via **ReturnedArrayLength \
*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](#signature-int32_t--maxoneelement-java-owned)\]\[[2](#signature-const-int32_t--maxoneelement-java-owned)\]
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](#signature-int32_t3-constelemcount-3-parent-owned)\] | 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](#signature-int32_t--constelemcount-3-natively-owned)\] | 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](#signature-int32_t--freesize-java-owned)\]
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](#signature-const-int32_t--freesize-java-owned)\]
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](#signature-int32_t--customsize-ambiguous-ownership)\]
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](#signature-const-int32_t--customsize-ambiguous-ownership)\]
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|
### Struct Java Signature Examples
#### Signature `int32_t *` MaxOneElement, Java owned
* `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:
* field-type (PointerType) 'int32_t *' -> (int32_t) * , size [fixed false, lnx64 8], const[false], pointer*1
* referenced (IntType) typedef 'int32_t', size [fixed true, lnx64 4], const[false], int
Will reuse memory if existing, otherwise allocating memory.
#### Signature `const int32_t *` MaxOneElement, Java owned
* `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:
* field-type (PointerType) 'int32_t *' -> (const int32_t) * , size [fixed false, lnx64 8], const[false], pointer*1
* referenced (IntType) typedef 'int32_t', size [fixed true, lnx64 4], const[native, true], int
Always replaces memory due to `const` value modifier.
#### Signature `int32_t[3]` ConstElemCount 3, Parent owned
* `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:
* src the source array of elements
* srcPos starting element position within the source array with 'srcPos >= 0` && `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
* length the element count to be copied with 'length >= 0` && `srcPos + length <= src.length` && `destPos + length <= elemCount`, otherwise an IndexOutOfBoundsException is thrown
Returns:
* this instance of chaining
#### Signature `int32_t *` ConstElemCount 3, Natively owned
* `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:
* field-type (PointerType) 'int32_t *' -> (int32_t) * , size [fixed false, lnx64 8], const[false], pointer*1
* referenced (IntType) typedef 'int32_t', size [fixed true, lnx64 4], const[false], int
Copies the given source elements into the respective field's existing memory.
Parameters:
* src the source array of elements
* srcPos starting element position within the source array with 'srcPos >= 0` && `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
* length the element count to be copied with 'length >= 0` && `srcPos + length <= src.length` && `destPos + length <= elemCount`, otherwise an IndexOutOfBoundsException is thrown
Returns:
* this instance of chaining
#### Signature `int32_t *` FreeSize, Java owned
* `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:
* field-type (PointerType) 'int32_t *' -> (int32_t) * , size [fixed false, lnx64 8], const[false], pointer*1
* referenced (IntType) typedef 'int32_t', size [fixed true, lnx64 4], const[false], int
Copies the given source elements into the respective field, either writing into the existing memory or creating a new memory and referencing it.
Parameters:
* subset if `true` keeps the underlying memory and only allows to set up to `elemCount` elements. Otherwise may replace the underlying memory if `destPos + length != elemCount`.
* src the source array of elements
* srcPos starting element position within the source array with 'srcPos >= 0` && `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
* length the element count to be copied with 'length >= 0` && `srcPos + length <= src.length`, otherwise an IndexOutOfBoundsException is thrown
Returns:
* this instance of chaining
#### Signature `const int32_t *` FreeSize, Java owned
* `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:
* field-type (PointerType) 'int32_t *' -> (const int32_t) * , size [fixed false, lnx64 8], const[false], pointer*1
* referenced (IntType) typedef 'int32_t', size [fixed true, lnx64 4], const[native, true], int
Replaces the respective field's memory with a new memory segment containing given source elements and referencing it.
Parameters:
* src the source array of elements
* srcPos starting element position within the source array with 'srcPos >= 0` && `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 thrown
Returns:
* this instance of chaining
#### Signature `int32_t *` CustomSize, Ambiguous ownership
* `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:
* field-type (PointerType) 'int32_t *' -> (int32_t) * , size [fixed false, lnx64 8], const[false], pointer*1
* referenced (IntType) typedef 'int32_t', size [fixed true, lnx64 4], const[false], int
Copies the given source elements into the respective field, either writing into the existing memory or creating a new memory and referencing it.
Parameters:
* subset if `true` keeps the underlying memory and only allows to set up to `elemCount` elements. Otherwise may replace the underlying memory if `destPos + length != elemCount`.
* src the source array of elements
* srcPos starting element position within the source array with 'srcPos >= 0` && `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
* length the element count to be copied with 'length >= 0` && `srcPos + length <= src.length`, otherwise an IndexOutOfBoundsException is thrown
Returns:
* this instance of chaining
#### Signature `const int32_t *` CustomSize, Ambiguous ownership
* `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:
* field-type (PointerType) 'int32_t *' -> (const int32_t) * , size [fixed false, lnx64 8], const[false], pointer*1
* referenced (IntType) typedef 'int32_t', size [fixed true, lnx64 4], const[native, true], int
Replaces the respective field's memory with a new memory segment containing given source elements and referencing it.
Parameters:
* src the source array of elements
* srcPos starting element position within the source array with 'srcPos >= 0` && `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 thrown
Returns:
* this instance of chaining
### Struct Pointer-Pointer Support
See primitive [*Pointer Mapping*](#pointer-mapping) above.
*Pointer* are exposed in the following examples
```
typedef struct {
int32_t* int32PtrArray[10];
int32_t** int32PtrPtr;
...
} T2_PointerStorage;
```
or via and undefined forward-declared struct
```
typedef struct T2_UndefStruct* T2_UndefStructPtr;
typedef struct {
...
T2_UndefStructPtr undefStructPtr;
T2_UndefStructPtr undefStructPtrArray[10];
T2_UndefStructPtr* undefStructPtrPtr;
const T2_UndefStructPtr* constUndefStructPtrPtr;
} T2_PointerStorage;
```
and the following GlueGen configuration
```
Opaque long T2_UndefStruct*
Ignore T2_UndefStruct
```
*TODO: Enhance documentation*
### Struct Function-Pointer Support
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.
#### Example
Assume the following C Header file example:
```
typedef struct {
int32_t balance;
} T2_UserData;
typedef int32_t ( * T2_CustomFuncA)(void* aptr);
typedef int32_t ( * T2_CustomFuncB)(T2_UserData* pUserData);
typedef struct {
...
T2_CustomFuncA customFuncAVariantsArray[10];
T2_CustomFuncA* customFuncAVariantsArrayPtr;
T2_CustomFuncB customFuncBVariantsArray[10];
T2_CustomFuncB* customFuncBVariantsArrayPtr;
} T2_PointerStorage;
typedef struct {
...
const T2_CustomFuncA CustomFuncA1;
T2_CustomFuncB CustomFuncB1;
} T2_InitializeOptions;
```
and the following GlueGen configuration
```
Opaque long void*
EmitStruct T2_UserData
StructPackage T2_UserData com.jogamp.gluegen.test.junit.generation
EmitStruct T2_InitializeOptions
StructPackage T2_InitializeOptions com.jogamp.gluegen.test.junit.generation
```
This will lead to the following result for `const T2_CustomFuncA customFuncA1`
```
/**
* Getter for native field CustomFuncA1
, being a struct owned function pointer.
* (PointerType) typedef 'T2_CustomFuncA' -> int32_t (*)(void * aptr), size [fixed false, lnx64 8], const[false], pointer*1, funcPointer
*
int32_t CustomFuncA1(void * aptr)
*/
public final int CustomFuncA1(long aptr) { ... }
```
and similar to `T2_CustomFuncB customFuncB1`
```
/**
* Setter for native field CustomFuncB1
, being a struct owned function pointer.
* (PointerType) typedef 'T2_CustomFuncB' -> int32_t (*)(T2_UserData * pUserData), size [fixed false, lnx64 8], const[false], pointer*1, funcPointer
* CustomFuncB1
, being a struct owned function pointer.
* (PointerType) typedef 'T2_CustomFuncB' -> int32_t (*)(T2_UserData * pUserData), size [fixed false, lnx64 8], const[false], pointer*1, funcPointer
*
int32_t CustomFuncB1(T2_UserData * pUserData)
*/
public final int CustomFuncB1(T2_UserData pUserData) { .. }
```
## Java Callback
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 Details
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.
### *JavaCallback* *UserParam* Mapping
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](#javacallback-configuration).
The following mappings are supported.
#### Pure Java Object User Type (default)
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*](#custom-callback-userparamclass) can be specified [in the configuration](#javacallback-configuration), which is recommended for more clarity in the resulting API.
#### Struct Type User Param (Homogeneous)
A [GlueGen generated *Struct type*](#struct-mapping) 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`.
#### Struct Type User Param (Heterogeneous)
An anonymous pointer (*long*) for `SetCallbackFunctionName` and a [GlueGen generated *struct type*](#struct-mapping) 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](#javacallback-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`.
### *JavaCallback* Configuration
Configuration directives are as follows:
JavaCallbackDef
void callback(size_t id, const char * msg, void * usrParam)
Alias for: T2_CallbackFunc01
*/
public void callback(long id, String msg, Object usrParam);
}
...
/** Entry point (through function pointer) to C language function:
void MessageCallback01(T2_CallbackFunc01 cbFunc, void * usrParam)
*/
public void MessageCallback01(T2_CallbackFunc01 cbFunc, Object usrParam);
/** Returns if callback is mapped for
public void MessageCallback01(T2_CallbackFunc01 cbFunc, Object usrParam)
**/
public boolean isMessageCallback01Mapped();
/** Returns T2_CallbackFunc01 callback for
public void MessageCallback01(T2_CallbackFunc01 cbFunc, Object usrParam)
**/
public T2_CallbackFunc01 getMessageCallback01();
/** Returns user-param for
public void MessageCallback01(T2_CallbackFunc01 cbFunc, Object usrParam)
**/
public Object getMessageCallback01UserParam();
/** Releases callback data skipping toolkit API. Favor passing `null` callback ref to
public void MessageCallback01(T2_CallbackFunc01 cbFunc, Object usrParam)
**/
public void releaseMessageCallback01();
/** Entry point (through function pointer) to C language function:
void InjectMessageCallback01(size_t id, const char * msg)
*/
public void InjectMessageCallback01(long id, String msg);
```
### JavaCallback Example 2a (Default *KeyClass*)
This example demonstrates a [homogeneous *Java Object* `UserParam` mapping](#pure-java-object-user-type-default) with a [key-mapped](#javacallback-key-definition) `CallbackFunction` and `UserParam`.
Additionally a [custom *UserParamClass*](#custom-callback-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
```
typedef void ( * ALBUFFERCALLBACKTYPESOFT)(int buffer /* key */, void *userptr, int sampledata, int numbytes);
void alBufferCallback0(int buffer /* key */, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, void *userptr);
void alBufferCallback0Inject(int buffer, int sampledata, int numbytes);
```
and the following GlueGen configuration
```
# Define a JavaCallback.
# Set JavaCallback via function `alBufferCallback0` if `ALBUFFERCALLBACKTYPESOFT` argument is non-null, otherwise removes the mapped callback and associated resources.
#
# It uses the function-pointer argument `ALBUFFERCALLBACKTYPESOFT` as the callback function type
# and marks `ALBUFFERCALLBACKTYPESOFT`s 2nd argument (index 1) as the mandatory user-param.
#
# This callback defines one key, `buffer`, index 0 of alBufferCallback0(..) parameter list, limiting it to buffer-name scope!
# The `buffer` key allows setting one callback per buffer-name, compatible with the `AL_SOFT_callback_buffer` spec.
#
# Explicit queries are generated, passing the keys as paramters
# - `Set
void callback(int buffer, void * userptr, int sampledata, int numbytes)
Alias for: ALBUFFERCALLBACKTYPESOFT
*/
public void callback(int buffer, ALCcontext userptr, int sampledata, int numbytes);
}
...
/** Key { int buffer } for
public void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, Object userptr)
**/
public static class AlBufferCallback0Key {
public final int buffer;
public AlBufferCallback0Key(int buffer) {
this.buffer = buffer;
}
@Override
public boolean equals(final Object o) {
if( this == o ) {
return true;
}
if( !(o instanceof AlBufferCallback0Key) ) {
return false;
}
final AlBufferCallback0Key o2 = (AlBufferCallback0Key)o;
return buffer == o2.buffer;
}
@Override
public int hashCode() {
// 31 * x == (x << 5) - x
int hash = buffer;
return hash;
}
}
...
/** Returns set of Key { int buffer } for
void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, ALCcontext userptr)
*/
public Set
void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, ALCcontext userptr)
*/
public boolean isAlBufferCallback0Mapped(AlBufferCallback0Key key);
/** Returns ALBUFFERCALLBACKTYPESOFT callback mapped to Key { int buffer } for
void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, ALCcontext userptr)
*/
public ALBUFFERCALLBACKTYPESOFT getAlBufferCallback0(AlBufferCallback0Key key);
/** Returns user-param mapped to Key { int buffer } for
void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, ALCcontext userptr)
*/
public ALCcontext getAlBufferCallback0UserParam(AlBufferCallback0Key key);
/** Releases all callback data mapped via Key { int buffer } skipping toolkit API. Favor passing `null` callback ref to
void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, ALCcontext userptr)
*/
public int releaseAllAlBufferCallback0();
/** Releases callback data mapped to Key { int buffer } skipping toolkit API. Favor passing `null` callback ref to
void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, ALCcontext userptr)
*/
public void releaseAlBufferCallback0(AlBufferCallback0Key key);
/** Entry point (through function pointer) to C language function:
void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, void * userptr)
*/
public void alBufferCallback0(int buffer, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback, ALCcontext userptr);
/** Entry point (through function pointer) to C language function:
void alBufferCallback0Inject(int buffer, int sampledata, int numbytes)
*/
public void alBufferCallback0Inject(int buffer, int sampledata, int numbytes);
```
### JavaCallback Example 2b (Custom *KeyClass*, different key-parameter order)
Similar example as example 2a, but using a [custom *KeyClass*](#custom-callback-keyclass) to map `CallbackFunction` and `UserParam` and also accommodating a different key-parameter order between `SetCallbackFunction` and `CallbackFunction`.
C-API Header snipped
```
typedef void ( * ALBUFFERCALLBACKTYPESOFT)(int buffer /* key */, void *userptr, int sampledata, int numbytes);
void alBufferCallback1(void *user_ptr, int buffer_key /* key */, int format, int freq, ALBUFFERCALLBACKTYPESOFT callback);
void alBufferCallback1Inject(int buffer, int sampledata, int numbytes);
```
GlueGen configuration snippet with the added option attribute for the `Callback-KeyClass` in directive `JavaCallbackDef`.
```
JavaCallbackDef alBufferCallback1 0 ALBUFFERCALLBACKTYPESOFT 1 ALCcontext com.jogamp.gluegen.test.junit.generation.BaseClass4JavaCallback.CustomAlBufferCallback1Key
JavaCallbackKey alBufferCallback1 1 ALBUFFERCALLBACKTYPESOFT 0
```
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`.
```
public static class CustomAlBufferCallback1Key {
private final int buffer;
public CustomAlBufferCallback1Key(final int buffer) {
this.buffer = buffer;
}
@Override
public boolean equals(final Object o) {
if( this == o ) {
return true;
}
if( !(o instanceof CustomAlBufferCallback1Key) ) {
return false;
}
final CustomAlBufferCallback1Key o2 = (CustomAlBufferCallback1Key)o;
return buffer == o2.buffer;
}
@Override
public int hashCode() {
return buffer;
}
@Override
public String toString() {
return "CustomALKey[this "+toHexString(System.identityHashCode(this))+", buffer "+buffer+"]";
}
}
```
### JavaCallback Example 5b (UserParam part of 2 component-key)
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
```
typedef void ( * ALEVENTPROCSOFT)(int eventType, int object, int param, int length, const char *message, void *userParam /* key */);
void alEventCallback1(int object /* key */, ALEVENTPROCSOFT callback, void *userParam /* key */);
```
GlueGen configuration snippet with the added option attribute for the `Callback-UserParamClass` in directive `JavaCallbackDef`.
```
ArgumentIsPascalString ALEVENTPROCSOFT 3 4
JavaCallbackDef alEventCallback1 2 ALEVENTPROCSOFT 5 ALCcontext
JavaCallbackKey alEventCallback1 0 2 ALEVENTPROCSOFT 1 5
```
Resulting to the default `KeyClass`
```
/** Key { int object, ALCcontext userParam } for
void alEventCallback1(int object, ALEVENTPROCSOFT callback, ALCcontext userParam)
*/
public static class AlEventCallback1Key {
public final int object;
public final ALCcontext userParam;
public AlEventCallback1Key(int object, ALCcontext userParam) {
this.object = object;
this.userParam = userParam;
}
@Override
public boolean equals(final Object o) {
if( this == o ) {
return true;
}
if( !(o instanceof AlEventCallback1Key) ) {
return false;
}
final AlEventCallback1Key o2 = (AlEventCallback1Key)o;
return object == o2.object &&
userParam == o2.userParam;
}
@Override
public int hashCode() {
// 31 * x == (x << 5) - x
int hash = object;
hash = ((hash << 5) - hash) + System.identityHashCode( userParam );
return hash;
}
}
```
### JavaCallback Example 11a (*Homogeneous Struct Type*)
This example demonstrates a [homogeneous *Struct* `UserParam` mapping](#struct-type-user-param-homogeneous) with a [key-mapped](#javacallback-key-definition) `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
```
typedef struct {
int32_t ApiVersion;
void* Data;
long i;
long r;
size_t id;
} T2_Callback11UserType;
typedef void ( * T2_CallbackFunc11)(size_t id, const T2_Callback11UserType* usrParam, long val);
void MessageCallback11a(size_t id /* key */, T2_CallbackFunc11 cbFunc, const T2_Callback11UserType* usrParam);
void MessageCallback11aInject(size_t id, long val);
```
and the following GlueGen configuration
```
JavaCallbackDef MessageCallback11a 2 T2_CallbackFunc11 1
JavaCallbackKey MessageCallback11a 0 T2_CallbackFunc11 0
```
leading to the following interface
```
/** JavaCallback interface: T2_CallbackFunc11 -> void (*T2_CallbackFunc11)(size_t id, const T2_Callback11UserType * usrParam, long val) */
public static interface T2_CallbackFunc11 {
/** Interface to C language function:
void callback(size_t id, const T2_Callback11UserType * usrParam, long val)
Alias for: T2_CallbackFunc11
*/
public void callback(long id, T2_Callback11UserType usrParam, long val);
}
...
public static class MessageCallback11aKey { ... }
...
/** Returns set of Key { long id } for
void MessageCallback11a(long id, T2_CallbackFunc11 cbFunc, T2_Callback11UserType usrParam)
*/
public Set
void MessageCallback11a(long id, T2_CallbackFunc11 cbFunc, T2_Callback11UserType usrParam)
*/
public boolean isMessageCallback11aMapped(MessageCallback11aKey key);
/** Returns T2_CallbackFunc11 callback mapped to Key { long id } for
void MessageCallback11a(long id, T2_CallbackFunc11 cbFunc, T2_Callback11UserType usrParam)
*/
public T2_CallbackFunc11 getMessageCallback11a(MessageCallback11aKey key);
/** Returns user-param mapped to Key { long id } for
void MessageCallback11a(long id, T2_CallbackFunc11 cbFunc, T2_Callback11UserType usrParam)
*/
public T2_Callback11UserType getMessageCallback11aUserParam(MessageCallback11aKey key);
/** Releases all callback data mapped via Key { long id } skipping toolkit API. Favor passing `null` callback ref to
void MessageCallback11a(long id, T2_CallbackFunc11 cbFunc, T2_Callback11UserType usrParam)
*/
public int releaseAllMessageCallback11a();
/** Releases callback data mapped to Key { long id } skipping toolkit API. Favor passing `null` callback ref to
void MessageCallback11a(long id, T2_CallbackFunc11 cbFunc, T2_Callback11UserType usrParam)
*/
public void releaseMessageCallback11a(MessageCallback11aKey key);
/** Entry point (through function pointer) to C language function:
void MessageCallback11a(size_t id, T2_CallbackFunc11 cbFunc, const T2_Callback11UserType * usrParam)
*/
public void MessageCallback11a(long id, T2_CallbackFunc11 cbFunc, T2_Callback11UserType usrParam);
/** Entry point (through function pointer) to C language function:
void MessageCallback11aInject(size_t id, long val)
*/
public void MessageCallback11aInject(long id, long val);
```
### JavaCallback Example 11b (*Heterogeneous Pointer/Struct Type*)
This example demonstrates a [heterogeneous *Struct* `UserParam` mapping](#struct-type-user-param-heterogeneous) with a [key-mapped](#javacallback-key-definition) `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
```
typedef struct {
int32_t ApiVersion;
void* Data;
long i;
long r;
size_t id;
} T2_Callback11UserType;
typedef void ( * T2_CallbackFunc11)(size_t id, const T2_Callback11UserType* usrParam, long val);
void MessageCallback11b(size_t id /* key */, T2_CallbackFunc11 cbFunc, void* Data);
void MessageCallback11bInject(size_t id, long val);
```
and the following GlueGen configuration
```
JavaCallbackDef MessageCallback11b 2 T2_CallbackFunc11 1
JavaCallbackKey MessageCallback11b 0 T2_CallbackFunc11 0
```
leading to the following interface
```
/** JavaCallback interface: T2_CallbackFunc11 -> void (*T2_CallbackFunc11)(size_t id, const T2_Callback11UserType * usrParam, long val) */
public static interface T2_CallbackFunc11 {
/** Interface to C language function:
void callback(size_t id, const T2_Callback11UserType * usrParam, long val)
Alias for: T2_CallbackFunc11
*/
public void callback(long id, T2_Callback11UserType usrParam, long val);
}
...
public static class MessageCallback11bKey { ... }
...
/** Returns set of Key { long id } for
void MessageCallback11b(long id, T2_CallbackFunc11 cbFunc, long Data)
*/
public Set
void MessageCallback11b(long id, T2_CallbackFunc11 cbFunc, long Data)
*/
public boolean isMessageCallback11bMapped(MessageCallback11bKey key);
/** Returns T2_CallbackFunc11 callback mapped to Key { long id } for
void MessageCallback11b(long id, T2_CallbackFunc11 cbFunc, long Data)
*/
public T2_CallbackFunc11 getMessageCallback11b(MessageCallback11bKey key);
/** Returns user-param mapped to Key { long id } for
void MessageCallback11b(long id, T2_CallbackFunc11 cbFunc, long Data)
*/
public Object getMessageCallback11bUserParam(MessageCallback11bKey key);
/** Releases all callback data mapped via Key { long id } skipping toolkit API. Favor passing `null` callback ref to
void MessageCallback11b(long id, T2_CallbackFunc11 cbFunc, long Data)
*/
public int releaseAllMessageCallback11b();
/** Releases callback data mapped to Key { long id } skipping toolkit API. Favor passing `null` callback ref to
void MessageCallback11b(long id, T2_CallbackFunc11 cbFunc, long Data)
*/
public void releaseMessageCallback11b(MessageCallback11bKey key);
/** Entry point (through function pointer) to C language function:
void MessageCallback11b(size_t id, T2_CallbackFunc11 cbFunc, void * Data)
*/
public void MessageCallback11b(long id, T2_CallbackFunc11 cbFunc, long Data);
/** Entry point (through function pointer) to C language function:
void MessageCallback11bInject(size_t id, long val)
*/
public void MessageCallback11bInject(long id, long val);
```
### JavaCallback Example 12 (Without UserParam)
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
```
typedef enum {
LOG_Off = 0,
LOG_Fatal = 100,
LOG_Error = 200,
LOG_Warning = 300,
LOG_Info = 400,
LOG_Verbose = 500,
LOG_VeryVerbose = 600
} LogLevel;
typedef struct {
const char* Category;
const char* Message;
LogLevel Level;
} LogMessage;
typedef void ( * T2_CallbackFunc12)(const LogMessage* usrParam);
void SetLogCallBack(T2_CallbackFunc12 cbFunc);
void LogCallBackInject(const LogMessage* message);
```
and the following GlueGen configuration
```
ReturnsStringOnly LogMessage.Category
ReturnsStringOnly LogMessage.Message
JavaCallbackDef SetLogCallBack -1 T2_CallbackFunc12 -1
```
leading to the following interface
```
/** JavaCallback interface: T2_CallbackFunc12 -> void (*T2_CallbackFunc12)(const LogMessage * usrParam) */
public static interface T2_CallbackFunc12 {
/** Interface to C language function:
void callback(const LogMessage * usrParam)
Alias for: T2_CallbackFunc12
*/
public void callback(LogMessage usrParam);
}
...
/** Returns if callback is mapped for
void SetLogCallBack(T2_CallbackFunc12 cbFunc)
*/
public boolean isSetLogCallBackMapped();
/** Returns T2_CallbackFunc12 callback for
void SetLogCallBack(T2_CallbackFunc12 cbFunc)
*/
public T2_CallbackFunc12 getSetLogCallBack();
/** Releases callback data skipping toolkit API. Favor passing `null` callback ref to
void SetLogCallBack(T2_CallbackFunc12 cbFunc)
*/
public void releaseSetLogCallBack();
/** Entry point (through function pointer) to C language function:
void SetLogCallBack(T2_CallbackFunc12 cbFunc)
*/
public void SetLogCallBack(T2_CallbackFunc12 cbFunc);
/** Entry point (through function pointer) to C language function:
void LogCallBackInject(const LogMessage * message)
*/
public void LogCallBackInject(LogMessage message);
```
*TODO: Enhance documentation*
## Misc Configurations
### `LibraryOnLoad