diff options
author | Sven Gothel <[email protected]> | 2023-08-14 04:22:25 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2023-08-14 04:22:25 +0200 |
commit | fd623305d90a88fd01dea3dccf6b9fe76b19703f (patch) | |
tree | c5bdaad79e250332f20ff91f14b4f0f7421ad3ee | |
parent | 9b825a445c3d2646546306c1815f498406e2f8c3 (diff) |
Bug 1449: Convert manual/index.html to `gfm` (GitHub-Flavored Markdown) using markdown -> manual/index.md and add conversion recipes + make/scripts/md2html_update.sh
Noyte: Additionally edited 'doc/misc/macos_nativelib_dependencies.md`
to include `Use explicit OpenJDK/Temurin JDK `java` executable path`
as a workaround to pass `DYLD_LIBRARY_PATH` to `/usr/bin/java`.
-rw-r--r-- | doc/GlueGen_Mapping.html | 24 | ||||
-rw-r--r-- | doc/GlueGen_Mapping.md | 24 | ||||
-rwxr-xr-x | doc/manual/index.html | 4391 | ||||
-rw-r--r-- | doc/manual/index.md | 1855 | ||||
-rw-r--r-- | doc/misc/macos_nativelib_dependencies.html | 485 | ||||
-rw-r--r-- | doc/misc/macos_nativelib_dependencies.md | 17 | ||||
-rwxr-xr-x | make/scripts/md2html_update.sh | 11 |
7 files changed, 4485 insertions, 2322 deletions
diff --git a/doc/GlueGen_Mapping.html b/doc/GlueGen_Mapping.html index a8936af..6c8bc6e 100644 --- a/doc/GlueGen_Mapping.html +++ b/doc/GlueGen_Mapping.html @@ -490,6 +490,20 @@ </ul></li> </ul> </nav> +<!--- +We convert markdown using pandoc using `gfm` (GitHub-Flavored Markdown) as source format +and `html5+smart` with a custom template as the target. + +Recipe: +``` + ~/pandoc-buttondown-cgit/pandoc_md2html_local.sh GlueGen_Mapping.md > GlueGen_Mapping.html +``` + +Git repos: +- https://jausoft.com/cgit/users/sgothel/pandoc-buttondown-cgit.git/about/ +- https://github.com/sgothel/pandoc-buttondown-cgit +--> + <style> table, th, td { border: 1px solid black; @@ -498,6 +512,10 @@ table, th, td { <h1 id="gluegen-native-data--function-mapping-for-java">GlueGen Native Data & Function Mapping for Java™</h1> +<p><em>Disclaimer: This documented shall be synchronized with source +code, especially the configuration options.</em></p> +<p>Please also consider reading <a href="manual/index.html">GlueGen +Manual</a> for details on native data and function mappings.</p> <h2 id="references">References</h2> <ul> <li><a href="https://jogamp.org/cgit/gluegen.git/about/">GlueGen Git @@ -505,12 +523,10 @@ Repo</a></li> <li><a href="https://jogamp.org/deployment/jogamp-next/javadoc/gluegen/javadoc/">GlueGen Java™ API-Doc</a></li> -<li><a href="https://jogamp.org/gluegen/doc/manual/">GlueGen -Manual</a></li> +<li><a href="manual/index.html">GlueGen Manual</a></li> <li><a href="https://jogamp.org/gluegen/www/">GlueGen Project Page</a></li> -<li><a href="https://jogamp.org/gluegen/doc/HowToBuild.html">How To -Build</a></li> +<li><a href="HowToBuild.html">How To Build</a></li> </ul> <h2 id="overview">Overview</h2> <p><a href="https://jogamp.org/gluegen/www/">GlueGen</a> is a compiler diff --git a/doc/GlueGen_Mapping.md b/doc/GlueGen_Mapping.md index 60795e2..b7caa54 100644 --- a/doc/GlueGen_Mapping.md +++ b/doc/GlueGen_Mapping.md @@ -1,3 +1,17 @@ +<!--- +We convert markdown using pandoc using `gfm` (GitHub-Flavored Markdown) as source format +and `html5+smart` with a custom template as the target. + +Recipe: +``` + ~/pandoc-buttondown-cgit/pandoc_md2html_local.sh GlueGen_Mapping.md > GlueGen_Mapping.html +``` + +Git repos: +- https://jausoft.com/cgit/users/sgothel/pandoc-buttondown-cgit.git/about/ +- https://github.com/sgothel/pandoc-buttondown-cgit +--> + <style> table, th, td { border: 1px solid black; @@ -6,13 +20,19 @@ table, th, td { # 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](https://jogamp.org/gluegen/doc/manual/) +- [GlueGen Manual](manual/index.html) - [GlueGen Project Page](https://jogamp.org/gluegen/www/) -- [How To Build](https://jogamp.org/gluegen/doc/HowToBuild.html) +- [How To Build](HowToBuild.html) ## Overview [GlueGen](https://jogamp.org/gluegen/www/) is a compiler for function and data-structure declarations, diff --git a/doc/manual/index.html b/doc/manual/index.html index bd32af4..f811c3c 100755 --- a/doc/manual/index.html +++ b/doc/manual/index.html @@ -1,2127 +1,1959 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0"/> - <link href="../../../style.css" rel="stylesheet" type="text/css"/> - <link href="../../../style-alt1.css" rel="alternate stylesheet" title="default sans-serif font" type="text/css"/> - <title>Gluegen Manual</title> - </head> - <body> - <div id="container"> - <div id="header"> - <div id="slogan">Gluegen Manual</div> - <div id="logo"><a href="http://jogamp.org/">Gluegen</a></div> - </div> - <div id="menu"> - <ul> - <li><a href="http://jogamp.org/">Home</a></li> - <li><a href="../../../gluegen/www/">Gluegen</a></li> - <li><a href="../../../joal/www/">JOAL</a></li> - <li><a href="../../../jocl/www/">JOCL</a></li> - <li><a href="../../../jogl/www/">JOGL</a></li> - <li><a href="../../../demos/">Demos</a></li> - <li><a href="../../../wiki/">Wiki</a></li> - <li><a href="../../../deployment/gluegen-next/javadoc/">JavaDoc</a></li> - </ul> - </div> - <div id="main"> - <div id="text" class="fill"> - <h1>GlueGen Manual</h1> - - <i>Disclaimer: This documented shall be synchronized with source code, especially the confifuration options.</i> - <p> - Please also consider reading <a href="../GlueGen_Mapping.html">GlueGen Native Data & Function Mapping</a> for details on native data and function mappings. - </p> - - <h2> Table of Contents </h2> - - <a href="#Chapter1">Chapter 1</a> - Introduction - <ul> - <li> <a href = "#SecIntroduction">Introduction</a></li> - <li> <a href = "#SecStructure">Structure of the Generated Glue Code</a></li> - <li> <a href = "#SecUnique">Unique Features</a></li> - <li> <a href = "#SecBackground">Background and Design Principles</a></li> - </ul> - - <a href="#Chapter2">Chapter 2</a> - Using GlueGen - <ul> - <li> <a href = "#SecAcquiring">Acquiring and Building GlueGen</a> - <ul> - <li> <a href = "#SecCommon">Common Build Problems</a></li> - </ul> - </li> - <li> <a href = "#SecBasic">Basic Operation</a></li> - <li> <a href = "#SecAnt">Running GlueGen as an Ant Task</a></li> - <li> <a href = "#SecJCPP">JCPP</a></li> - <li> <a href = "#SecError">Error Reporting</a></li> - <li> <a href = "#SecStub">Stub Headers</a></li> - <li> <a href = "#Sec32">32- and 64-bit Considerations</a></li> - <li> <a href = "#SecOpaque">Opaque Directives</a></li> - <li> <a href = "#SecSubstitution">Argument Name Substitution</a></li> - <li> <a href = "#SecConfiguration">Configuration File Directives</a> - <ul> - <li> <a href = "#SecJavaEmitter">JavaEmitter Configuration</a></li> - <li> <a href = "#SecProcAddressEmitter">ProcAddressEmitter Configuration</a></li> - </ul> - </li> - </ul> - - <a href="#Chapter3">Chapter 3</a> - Configuration File Examples<br/> - <ul> - <li> <a href = "#SecSimplest">Simplest possible example</a></li> - <li> <a href = "#SecArrays">Arrays and buffers</a></li> - <li> <a href = "#SecString">String handling</a></li> - <li> <a href = "#SecMemory">Memory allocation</a></li> - <li> <a href = "#SecStructs">Ingoing and outgoing structs</a></li> - <li> <a href = "#SecStructArrays">Returned arrays of structs</a></li> - <li> <a href = "#SecPointerArrays">Returned arrays of pointers</a></li> - </ul> - - <h2> <a name="Chapter1">Chapter 1 - Introduction</a> </h2> - - <h3> <a name="SecIntroduction">Introduction</a> </h3> - - <p> - - GlueGen is a tool which automatically generates the Java and JNI code - necessary to call C libraries. It reads as input 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 is currently powerful enough to - bind even low-level APIs such as the Java Native Interface (JNI) and - the AWT Native Interface (JAWT) back up to the Java programming - language. - - </p> - <p> - - GlueGen is currently used to generate the JOGL interface to the OpenGL - 3D graphics API and the JOAL interface to the OpenAL audio library. In - the case of JOGL, GlueGen is used not only to bind OpenGL to Java, but - also the low-level windowing system APIs on the Windows, X11 and Mac - OS X platforms. The implementation of the JOGL library is thereby - written in the Java programming language rather than in C, which has - offered considerable advantages during the development of the library. - - </p> - - <p> - GlueGen is designed in modular form and can be extended to alter the - glue code emission style or to generate interface code for other - languages than Java. - </p> - - <p> - - This manual describes how to use GlueGen to bind new C libraries to - the Java programming language. - </p> - - <h3> <a name="SecStructure">Structure of the Generated Glue Code</a> </h3> - - <p> - - GlueGen supports two basic styles of glue code generation: everything - in one class, or a separate interface and implementing class. The - first mode, "AllStatic", exposes the underlying C functions as a set - of static Java methods in a concrete class. This is a straightforward - binding mechanism, but has the disadvantage of tying users to a - concrete class (which may or may not be a problem) and makes it more - difficult to support certain kinds of call-through-function-pointer - semantics required by certain C APIs. The second mode, - "InterfaceAndImpl", exposes the C functions as methods in an interface - and emits the implementation of that interface into a separate class - and package. The implementing class is not intended to be in the - public API; this more strongly separates the user from the - implementation of the API. Additionally, because it is necessary to - hold an instance of the implementing class in order to access the - underlying C routines, it is easier to support situations where - call-through-function-pointer semantics must be followed, in - particular where those function pointers might change from instance to - instance. - - </p> - The generated glue code follows some basic rules in binding C APIs to - Java: - <ul> - - <li> C primitive types are exposed as the corresponding Java primitive - type. - </li> - - <li> Pointers to typed C primitives (<code>int*</code>, - <code>float*</code>) are bound to java.nio Buffer subclasses - (<code>IntBuffer</code>, <code>FloatBuffer</code>) and optionally - to Java arrays (<code>int[]</code>, <code>float[]</code>). - <ul> - - <li> If a C function takes such a pointer as an outgoing argument, - two method overloadings will generally be produced; one which - accepts a Buffer, and one which accepts a primitive array plus - an integer offset argument. The variant taking a Buffer may - accept either a "direct" NIO Buffer or a non-direct one - (wrapping a Java array). The exception is when such a routine - is specified by the <a href="#NioDirectOnly">NioDirectOnly</a> - directive to keep a persistent pointer to the passed storage, - in which case only the Buffer variant will be generated, and - will only accept a direct Buffer as argument. - </li> - - <li> If a C function returns such a pointer as its result, it will - be exposed as the corresponding Buffer type. In this case it is - also typically necessary to specify to GlueGen via the <a - href="#ReturnValueCapacity">ReturnValueCapacity</a> directive - the number of addressable elements in the resulting array. - </li> - </ul> - </li> - <li> Pointers to <code>void*</code> are bound to java.nio.Buffer. - - <ul> - - <li> By default any C function accepting a <code>void*</code> - argument will allow either a direct or non-direct java.nio - Buffer to be passed as argument. If the <a - href="#NioDirectOnly">NioDirectOnly</a> directive is specified, - however, only a direct Buffer will be accepted. - </li> - <li> Similar rules for <code>void*</code> return values apply to - those for pointers to typed primitives. - </li> - </ul> - </li> - <li> To avoid an explosion in the number of generated methods, if a - particular API accepts more than one typed primitive pointer - argument, only two overloadings continue to be produced: one - accepting all arrays as arguments and one accepting all Buffers - as arguments. When calling the variant accepting Buffers, all of - the Buffers passed in a particular call must be either direct or - non-direct. Mixing of direct and non-direct Buffers in a given - function call is not supported. - </li> - <li> When a java.nio Buffer is passed from Java to C, the position of - the Buffer is taken into account. The resulting pointer passed to - C is equal to the base address of the Buffer plus the position - scaled appropriately for the size of the primitive elements in - the Buffer. This feature is called "auto-slicing", as it mimics - the behavior of calling Buffer.slice() without the overhead of - explicit object creation. - </li> - <li> Pointers to constant <code>char*</code> may be bound to - java.lang.String using the <a - href="#ArgumentIsString">ArgumentIsString</a> or <a - href="#ReturnsString">ReturnsString</a> directives. - </li> - <li> <code>#define</code> statements in header files mapping names to - constant values are exposed as public static final constant - values in either the generated interface or AllStatic class. - </li> - <li> C structs encountered during the glue code generation process and - referenced by the C functions are exposed as Java classes of the - same name (typically the name to which the struct is typedefed). - Each primitive field in the struct is exposed as two methods; a - getter, which accepts no arguments, and a setter, which accepts - as argument a primitive value of the type of the field. Static - factory methods are exposed allowing allocation of these structs - from Java code. The backing storage for these Java classes is a - direct java.nio Buffer. GlueGen fully supports returning of - pointers to C structs up to Java. - </li> - </ul> - - <h3><a name="SecUnique">Unique Features</a></h3> - - GlueGen contains several unique features making it both a powerful and - easy-to-use tool. - - <ul> - - <li> C structs are exposed as Java classes. The generated code for - these classes supports both 32-bit and 64-bit platforms. - </li> - <li> C structs containing function pointers are exposed as Java - classes with methods. This makes it easy to interact with - low-level C APIs such as the AWT Native Interface (JAWT) from the - Java programming language level. - - <ul> - - <li> In this context, GlueGen automatically detects which argument - to the various function pointers indicates the "this" pointer, - hiding it at the Java level and passing it automatically. - </li> - <li> GlueGen offers automatic handling of JNI-specific data types - such as <code>JNIEnv*</code> and <code>jobject</code>. The tool - understands that the <code>JNIEnv*</code> argument is implicit - and that <code>jobject</code> maps to java.lang.Object at the - Java programming language level. While this is most useful when - binding JDK-internal APIs such as the JAWT to Java, there may - be other JNI libraries which expose C functions taking these - data types, and GlueGen can very easily bind to them. - </li> - </ul> - </li> - </ul> - - <h3><a name="SecBackground">Background and Design Principles</a></h3> - - <p> - - This section provides motivation for the design of the GlueGen tool - and is not necessary to understand how to use the tool. - - </p> - <p> - - There are many tools available for assisting in the autogeneration of - foreign function interfaces for various high-level languages. Only a - few examples include <a - href="http://alumni.media.mit.edu/~kbrussel/Header2Scheme/">Header2Scheme</a>, - an early tool allowing binding of a limited subset of C++ to the - Scheme programming language; <a href="http://www.swig.org/">SWIG</a>, - a tool released at roughly the same time as Header2Scheme which by now - supports binding C and C++ libraries to a variety of scripting - languages; <a href="http://www.jniwrapper.com/">JNIWrapper</a>, a - commercial tool automating the binding of C APIs to Java; and <a - href="http://web.archive.org/web/20070419183658/http://www.noodleglue.org/noodleglue/noodleglue.html">NoodleGlue</a>, - a recently-released tool automating the binding of C++ APIs to - Java. Other language-specific tools such as Perl's XS, Boost.Python - and many others exist. - - </p> - <p> - - GlueGen was designed with a few key principles in mind. The most - fundamental was to support binding of the lowest-level APIs on a given - platform up to the Java programming language. The intended goal, in - the context of the JOGL project, was to allow subsets of the Win32 and - X11 APIs to be exposed to Java, and to use those APIs to write the - behind-the-scenes OpenGL context creation and management code in Java - instead of C. This informed several other design goals: - - </p> - <ul> - - <li> Avoid touching the C headers as much as possible. This makes it - easier to upgrade to a more recent version of the C API just by - copying in a new set of headers. - </li> - <li> Avoid touching the generated glue code completely.</li> - - <li> Avoid having to hand-write a lot of generated glue code. Instead, - handle many complex constructs automatically and provide - sufficient control over the glue code generation to avoid having - to handwrite certain native methods where one or two lines of - tweaking would suffice. - </li> - <li> Support all C constructs in the parser and intermediate - representation. The rationale is that it is acceptable to cut - corners in the number of constructs supported in the Java - binding, but not whether the tool can internally represent it in - its C type system. This design goal implies starting with - complete a ANSI C parser coupled with a complete C type system. - </li> - <li> As the tool is targetting the Java programming language, build - the tool in the Java programming language. - </li> - </ul> - - In order to make the problem more tractable, support for binding C++ - to the Java programming language was not considered. C++ adds many - constructs over ANSI C which make it much more difficult to reason - about and to find a useful subset to support binding to Java. - Additionally, it seems that there are relatively few C++-specific - libraries in general use which could be usefully bound to Java, - although this may be a matter of opinion. - - <p> - - GlueGen was designed with the Java programming language in mind, but - is not necessarily restricted to generating glue code for the Java - language. The tool is divided into separate parse and code generation - phases, and the internal representation is fairly easy to iterate - over. The core driver of GlueGen may therefore be useful in producing - other tools which autogenerate foreign function interfaces to C - libraries for other languages. - - </p> - - <h2> <a name="Chapter2">Chapter 2 - Using GlueGen</a> </h2> - - <h3><a name="SecAcquiring">Acquiring and Building GlueGen</a></h3> - - The source code for GlueGen may be obtained by cloning the Git repository: - - <pre> - $git clone --recursive git://jogamp.org/srv/scm/gluegen.git gluegen - </pre> - - To build GlueGen, cd into the gluegen/make folder and invoke ant. - <pre> - $ant clean all test - </pre> - Ant 1.8 or later and a Java 6 compatible JDK is required. - - <h4><a name="SecCommon">Common Build Problems</a></h4> - - - <dl> - <dt> <strong>CharScanner; panic: ClassNotFoundException: com.jogamp.gluegen.cgram.CToken</strong></dt> - <dd> This occurs because ANTLR was dropped into the Extensions - directory of the JRE/JDK. On Windows and Linux, delete any ANTLR - jars from jre/lib/ext, and on Mac OS X, delete them from - /Library/Java/Extensions. Use the antlr.jar property in the - build.xml to point to a JRE-external location of this jar file. - </dd> - </dl> - - - <h3><a name="SecBasic">Basic Operation</a></h3> - - <p> - - GlueGen can be run either as an executable jar file (<code>java -jar - gluegen.jar</code>; note that antlr.jar must be in the same directory - as gluegen.jar in order for this invocation to work) or from within - Ant as described in the following section. When run from the command - line, GlueGen accepts four kinds of command-line arguments: - </p> - <ul> - <li> -I<em>dir</em> (optional) adds <em>dir</em> to the include path. - Similarly to a C compiler or preprocessor, GlueGen scans a set of - directories to locate header files it encounters in - <code>#include</code> directives. Unlike most C preprocessors, - however, GlueGen has no default include path, so it is typically - necessary to supply at least one <code>-I</code> option on the - command line in order to handle any <code>#include</code> - directives in the file being parsed. - </li> - <li> -E<em>emitterClassName</em> (optional) uses - <em>emitterClassName</em> as the fully-qualified name of the - emitter class which will be used by GlueGen to generate the glue - code. The emitter class must implement the - <code>com.jogamp.gluegen.GlueEmitter</code> interface. If this - option is not specified, a - <code>com.jogamp.gluegen.JavaEmitter</code> will be used by default. - </li> - <li> -C<em>cfgFile</em> adds <em>cfgFile</em> to the list of - configuration files used to set up the chosen emitter. This is - the means by which a large number of options are passed in to the - GlueGen tool and to the emitter in particular. Configuration - files are discussed more in the following section. - </li> - <li> [ filename | - ] selects the file or standard input from which - GlueGen should read the C header file for which glue code should - be generated. This must be the last command-line argument, and - only one filename argument is supported. To cause multiple header - files to be parsed, write a small .c file #including the multiple - headers and point GlueGen at the .c file.</li> - </ul> - - <h3><a name="SecAnt">Running GlueGen as an Ant Task</a></h3> - - <p> - - GlueGen can also be invoked as a subtask within Ant. In order to do - so, a path element should be defined as follows: - </p> - <pre> - <path id="gluegen.classpath"> - <pathelement location="${gluegen.jar}" /> - <pathelement location="${antlr.jar}" /> - </path> - </pre> - - where the <code>gluegen.jar</code> and <code>antlr.jar</code> - properties point to the respective jar files. A taskdef defining the - GlueGen task should then be specified as follows: - - <pre> -<taskdef name="gluegen" - classname="com.jogamp.gluegen.ant.GlueGenTask" - classpathref="gluegen.classpath" /> - </pre> - - At this point GlueGen may be invoked as follows: - - <pre> -<gluegen src="[header to parse]" - config="[configuration file]" - includeRefid="[dirset for include path]" - emitter="com.jogamp.gluegen.JavaEmitter"> - <classpath refid="gluegen.classpath" /> -</gluegen> - </pre> - - Please see the <a href="http://jogamp.org/jogl/">JOGL</a> and <a - href="http://jogamp.org/joal/">JOAL</a> build.xml files for - concrete, though non-trivial, examples of how to invoke GlueGen via - Ant. - - <h3><a name="SecJCPP">JCPP</a></h3> - - <p> - - GlueGen contains and uses the <a href="https://jogamp.org/cgit/jcpp.git/about/">C preprocessor JCPP</a>, - see <a href="https://www.anarres.org/projects/jcpp/">original homepage</a>. - </p> - <p> - Constant values intended for use by end users are defined in many C - libraries' headers using <code>#define</code>s rather than constant - int declarations. If the header would be processed by a full C - preprocessor, the <code>#define</code> statement's macro name become - unavailable for processing by the glue code generator. - Using JCPP allows us to utilize the <code>#define</code> macro names and values. - </p> - <p> - JCPP is largely an invisible part of the glue code generation process. - If GlueGen's output is not as expected - and there is heavy use of the C preprocessor in the header, run JCPP - against the header directly (JCPP takes simply the -I and filename - arguments accepted by GlueGen) and examine the output. - </p> - - <h3><a name="SecStub">Stub Headers</a></h3> - - <p> - - As much as is possible, GlueGen is intended to operate on unmodified C - header files, so that it is easy to upgrade the given C API being - bound to Java simply by dropping in a new set of header files. - However, most C headers contain references to standard headers like - <code>stdio.h</code>, and if this header is parsed by GlueGen, the - tool will automatically attempt to generate Java entry points for such - routines as <code>fread</code> and <code>fwrite</code>, among others. - It is impractical to exclude these APIs on a case by case basis. - Therefore, the suggested technique to avoid polluting the binding with - these APIs is to "stub out" the headers. - - </p> - <p> - - GlueGen searches the include path for headers in the order the include - directories were specified to the tool. Placing another directory in - front of the one in which the bulk of the headers are found allows, - for example, an alternative <code>stdio.h</code> to be inserted which - contains few or no declarations but which satisfies the need of the - dependent header to find such a file. - - </p> - <p> - - GlueGen uses a complete ANSI and GNU C parser written by John Mitchell - and Monty Zukowski from the set of grammars available for the ANTLR - tool by Terrence Parr. As a complete C parser, this grammar requires - all data types encountered during the parse to be fully defined. Often - a particular header will be included by another one in order to pick - up data type declarations rather than API declarations. Stubbing out - the header with a smaller one providing a "fake" type declaration is a - useful technique for avoiding the binding of unnecessary APIs during - the glue code process. - - </p> - <p> - - Here's an example from the JOGL glue code generation process. The - <code>glext.h</code> header defining OpenGL extensions references - <code>stddef.h</code> in order to pick up the <code>ptrdiff_t</code> - data type. We choose to not include the real stddef.h but instead to - swap in a stub header. The contents of this header are therefore as - follows: - </p> - <pre> - #if defined(_WIN64) +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang=""> +<head> + <meta charset="utf-8" /> + <meta name="generator" content="pandoc" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> + <title>index.md</title> + <style> + div#header, header + { + + border-bottom: 1px solid #aaa; + margin-bottom: 0.5em; + } + + .title + { + text-align: center; + } + + .author, .date + { + text-align: center; + } + + div#TOC, nav#TOC + { + + border-bottom: 1px solid #aaa; + margin-bottom: 0.5em; + } + + nav#TOC { + margin-bottom: var(--line-height); + + padding-bottom: 0.5rem; + } + + nav#TOC input { + display: none; + } + + nav#TOC label { + color: var(--color-link); + cursor: pointer; + } + + nav#TOC > ul { + display: none; + } + + nav#TOC > input:checked + ul { + display: block; + } + + @media print + { + div#TOC, nav#TOC + { + + display: none; + } + } + + div.content + { + color: #111111; + font-size: 14px; + line-height: 1.6; + } + + div#cgit a + { + color: #1212a0; + } + + div#cgit a.sourceLine + { + color: #111111; + } + + h1, h2, h3, h4, h5, h6 + { + font-family: "Helvetica Neue", Helvetica, "Liberation Sans", Calibri, Arial, sans-serif; + + page-break-after: avoid; + + margin: 20px 0 10px; + padding: 0; + } + + h2 { + border-bottom: 1px solid #ccc; + } + + div div + { + + } + + section section + { + margin-left: 2em; + } + + p {} + + blockquote + { + font-style: italic; + } + + li + { + } + + li > p + { + margin-top: 1em; + } + + ul + { + } + + ul li + { + } + + ol + { + } + + ol li + { + } + + hr {} + + sub + { + } + + sup + { + } + + em + { + } + + em > em + { + font-style: normal; + } + + strong + { + } + + a + { + + text-decoration: none; + } + + @media screen + { + a:hover + { + + text-decoration: underline; + } + } + + @media print + { + a { + + color: black; + background: transparent; + } + + a[href^="http://"]:after, a[href^="https://"]:after + { + + content: " (" attr(href) ") "; + font-size: 90%; + } + } + + img + { + + vertical-align: middle; + } + + div.figure + { + + margin-left: auto; + margin-right: auto; + text-align: center; + font-style: italic; + } + + p.caption + { + + } + + pre, code + { + background-color: #f8f8f8; + + white-space: pre-wrap; + white-space: -moz-pre-wrap !important; + white-space: -pre-wrap; + white-space: -o-pre-wrap; + word-wrap: break-word; + + } + + pre + { + + padding: 0.5em; + border-radius: 5px; + + background-color: #f8f8f8; + border: 1px solid #ccc; + font-size: 13px; + line-height: 19px; + overflow: auto; + padding: 6px 10px; + + margin-left: 0.5em; + margin-right: 0.5em; + } + + @media screen + { + pre + { + + white-space: pre; + overflow: auto; + + border: 1px dotted #777; + } + } + + code + { + } + + p > code, li > code + { + + padding-left: 2px; + padding-right: 2px; + } + + li > p code + { + + padding: 2px; + } + + span.math + { + + } + + div.math + { + } + + span.LaTeX + { + } + + eq + { + } + + table + { + border-collapse: collapse; + border-spacing: 0; + + margin-left: auto; + margin-right: auto; + } + + thead + { + border-bottom: 1pt solid #000; + background-color: #eee; + } + + tr.header + { + } + + tbody + { + } + + tr { + } + tr.odd:hover, tr.even:hover + { + background-color: #eee; + } + + tr.odd {} + tr.even {} + + td, th + { + vertical-align: top; + vertical-align: baseline; + padding-left: 0.5em; + padding-right: 0.5em; + padding-top: 0.2em; + padding-bottom: 0.2em; + } + th + { + font-weight: bold; + } + + tfoot + { + } + + caption + { + caption-side: top; + border: none; + font-size: 0.9em; + font-style: italic; + text-align: center; + margin-bottom: 0.3em; + padding-bottom: 0.2em; + } + + dl + { + border-top: 2pt solid black; + padding-top: 0.5em; + border-bottom: 2pt solid black; + } + + dt + { + font-weight: bold; + } + + dd+dt + { + border-top: 1pt solid black; + padding-top: 0.5em; + } + + dd + { + margin-bottom: 0.5em; + } + + dd+dd + { + border-top: 1px solid black; + } + + a.footnote, a.footnoteRef { + font-size: small; + vertical-align: text-top; + } + + a[href^="#fnref"], a.reversefootnote + { + } + + @media print + { + a[href^="#fnref"], a.reversefootnote + { + + display: none; + } + } + + div.footnotes + { + } + + div.footnotes li[id^="fn"] + { + } + + @media print + { + .noprint + { + display:none; + } + } + </style> +</head> +<body> +<nav id="TOC" role="doc-toc"> + <strong>Contents</strong><label for="contents">⊕</label> + <input type="checkbox" id="contents"> + <ul> + <li><a href="#gluegen-manual">GlueGen Manual</a> + <ul> + <li><a href="#references">References</a></li> + <li><a href="#chapter-1---introduction"><span id="Chapter1">Chapter 1 + - Introduction</span></a> + <ul> + <li><a + href="#introduction"><span id="SecIntroduction">Introduction</span></a></li> + <li><a + href="#structure-of-the-generated-glue-code"><span id="SecStructure">Structure + of the Generated Glue Code</span></a></li> + <li><a href="#unique-features"><span id="SecUnique">Unique + Features</span></a></li> + <li><a + href="#background-and-design-principles"><span id="SecBackground">Background + and Design Principles</span></a></li> + </ul></li> + <li><a href="#chapter-2---using-gluegen"><span id="Chapter2">Chapter 2 + - Using GlueGen</span></a> + <ul> + <li><a + href="#acquiring-and-building-gluegen"><span id="SecAcquiring">Acquiring + and Building GlueGen</span></a></li> + <li><a href="#basic-operation"><span id="SecBasic">Basic + Operation</span></a></li> + <li><a + href="#running-gluegen-as-an-ant-task"><span id="SecAnt">Running + GlueGen as an Ant Task</span></a></li> + <li><a href="#jcpp"><span id="SecJCPP">JCPP</span></a></li> + <li><a href="#stub-headers"><span id="SecStub">Stub + Headers</span></a></li> + <li><a href="#32--and-64-bit-considerations"><span id="Sec32">32- and + 64-bit Considerations</span></a></li> + <li><a href="#opaque-directives"><span id="SecOpaque">Opaque + Directives</span></a></li> + <li><a + href="#argument-name-substitution"><span id="SecSubstitution">Argument + Name Substitution</span></a></li> + <li><a + href="#configuration-file-directives"><span id="SecConfiguration">Configuration + File Directives</span></a></li> + </ul></li> + <li><a + href="#chapter-3---configuration-file-examples"><span id="Chapter3">Chapter + 3 - Configuration File Examples</span></a> + <ul> + <li><a + href="#simplest-possible-example"><span id="SecSimplest">Simplest + possible example</span></a></li> + <li><a href="#arrays-and-buffers"><span id="SecArrays">Arrays and + buffers</span></a></li> + <li><a href="#string-handling"><span id="SecString">String + handling</span></a></li> + <li><a href="#memory-allocation"><span id="SecMemory">Memory + allocation</span></a></li> + <li><a + href="#ingoing-and-outgoing-structs"><span id="SecStructs">Ingoing and + outgoing structs</span></a></li> + <li><a + href="#returned-arrays-of-structs"><span id="SecStructArrays">Returned + arrays of structs</span></a></li> + <li><a + href="#returned-arrays-of-pointers"><span id="SecPointerArrays">Returned + arrays of pointers</span></a></li> + </ul></li> + </ul></li> + </ul> +</nav> +<!--- +We convert markdown using pandoc using `gfm` (GitHub-Flavored Markdown) as source format +and `html5+smart` with a custom template as the target. + +Recipe: +``` + ~/pandoc-buttondown-cgit/pandoc_md2html_local.sh index.md > index.html +``` + +Git repos: +- https://jausoft.com/cgit/users/sgothel/pandoc-buttondown-cgit.git/about/ +- https://github.com/sgothel/pandoc-buttondown-cgit +--> + +<style> +table, th, td { + border: 1px solid black; +} +</style> + +<h1 id="gluegen-manual">GlueGen Manual</h1> +<p><em>Disclaimer: This documented shall be synchronized with source +code, especially the configuration options.</em></p> +<p>Please also consider reading <a +href="../GlueGen_Mapping.html">GlueGen Native Data & Function +Mapping</a> for details on native data and function mappings.</p> +<h2 id="references">References</h2> +<ul> +<li><a href="https://jogamp.org/cgit/gluegen.git/about/">GlueGen Git +Repo</a></li> +<li><a +href="https://jogamp.org/deployment/jogamp-next/javadoc/gluegen/javadoc/">GlueGen +Java™ API-Doc</a></li> +</ul> +<ul> +<li><a href="../GlueGen_Mapping.html">GlueGen Native Data & Function +Mapping for Java™</a></li> +</ul> +<ul> +<li><a href="https://jogamp.org/gluegen/www/">GlueGen Project +Page</a></li> +<li><a href="../HowToBuild.html">How To Build</a></li> +</ul> +<h2 id="chapter-1---introduction"><span id="Chapter1">Chapter 1 - +Introduction</span></h2> +<h3 +id="introduction"><span id="SecIntroduction">Introduction</span></h3> +<p>GlueGen is a tool which automatically generates the Java and JNI code +necessary to call C libraries. It reads as input 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 is currently powerful enough to bind even low-level +APIs such as the Java Native Interface (JNI) and the AWT Native +Interface (JAWT) back up to the Java programming language.</p> +<p>GlueGen is currently used to generate the JOGL interface to the +OpenGL 3D graphics API and the JOAL interface to the OpenAL audio +library. In the case of JOGL, GlueGen is used not only to bind OpenGL to +Java, but also the low-level windowing system APIs on the Windows, X11 +and Mac OS X platforms. The implementation of the JOGL library is +thereby written in the Java programming language rather than in C, which +has offered considerable advantages during the development of the +library.</p> +<p>GlueGen is designed in modular form and can be extended to alter the +glue code emission style or to generate interface code for other +languages than Java.</p> +<p>This manual describes how to use GlueGen to bind new C libraries to +the Java programming language.</p> +<h3 +id="structure-of-the-generated-glue-code"><span id="SecStructure">Structure +of the Generated Glue Code</span></h3> +<p>GlueGen supports two basic styles of glue code generation: everything +in one class, or a separate interface and implementing class. The first +mode, "AllStatic", exposes the underlying C functions as a set of static +Java methods in a concrete class. This is a straightforward binding +mechanism, but has the disadvantage of tying users to a concrete class +(which may or may not be a problem) and makes it more difficult to +support certain kinds of call-through-function-pointer semantics +required by certain C APIs. The second mode, "InterfaceAndImpl", exposes +the C functions as methods in an interface and emits the implementation +of that interface into a separate class and package. The implementing +class is not intended to be in the public API; this more strongly +separates the user from the implementation of the API. Additionally, +because it is necessary to hold an instance of the implementing class in +order to access the underlying C routines, it is easier to support +situations where call-through-function-pointer semantics must be +followed, in particular where those function pointers might change from +instance to instance.</p> +<p>The generated glue code follows some basic rules in binding C APIs to +Java:</p> +<ul> +<li>C primitive types are exposed as the corresponding Java primitive +type.</li> +<li>Pointers to typed C primitives (<code>int*</code>, +<code>float*</code>) are bound to java.nio Buffer subclasses +(<code>IntBuffer</code>, <code>FloatBuffer</code>) and optionally to +Java arrays (<code>int[]</code>, <code>float[]</code>). +<ul> +<li>If a C function takes such a pointer as an outgoing argument, two +method overloadings will generally be produced; one which accepts a +Buffer, and one which accepts a primitive array plus an integer offset +argument. The variant taking a Buffer may accept either a "direct" NIO +Buffer or a non-direct one (wrapping a Java array). The exception is +when such a routine is specified by the <a +href="#NioDirectOnly">NioDirectOnly</a> directive to keep a persistent +pointer to the passed storage, in which case only the Buffer variant +will be generated, and will only accept a direct Buffer as +argument.</li> +<li>If a C function returns such a pointer as its result, it will be +exposed as the corresponding Buffer type. In this case it is also +typically necessary to specify to GlueGen via the <a +href="#ReturnValueCapacity">ReturnValueCapacity</a> directive the number +of addressable elements in the resulting array.</li> +</ul></li> +<li>Pointers to <code>void*</code> are bound to java.nio.Buffer. +<ul> +<li>By default any C function accepting a <code>void*</code> argument +will allow either a direct or non-direct java.nio Buffer to be passed as +argument. If the <a href="#NioDirectOnly">NioDirectOnly</a> directive is +specified, however, only a direct Buffer will be accepted.</li> +<li>Similar rules for <code>void*</code> return values apply to those +for pointers to typed primitives.</li> +</ul></li> +<li>To avoid an explosion in the number of generated methods, if a +particular API accepts more than one typed primitive pointer argument, +only two overloadings continue to be produced: one accepting all arrays +as arguments and one accepting all Buffers as arguments. When calling +the variant accepting Buffers, all of the Buffers passed in a particular +call must be either direct or non-direct. Mixing of direct and +non-direct Buffers in a given function call is not supported.</li> +<li>When a java.nio Buffer is passed from Java to C, the position of the +Buffer is taken into account. The resulting pointer passed to C is equal +to the base address of the Buffer plus the position scaled appropriately +for the size of the primitive elements in the Buffer. This feature is +called "auto-slicing", as it mimics the behavior of calling +Buffer.slice() without the overhead of explicit object creation.</li> +<li>Pointers to constant <code>char*</code> may be bound to +java.lang.String using the <a +href="#ArgumentIsString">ArgumentIsString</a> or <a +href="#ReturnsString">ReturnsString</a> directives.</li> +<li><code>#define</code> statements in header files mapping names to +constant values are exposed as public static final constant values in +either the generated interface or AllStatic class.</li> +<li>C structs encountered during the glue code generation process and +referenced by the C functions are exposed as Java classes of the same +name (typically the name to which the struct is typedefed). Each +primitive field in the struct is exposed as two methods; a getter, which +accepts no arguments, and a setter, which accepts as argument a +primitive value of the type of the field. Static factory methods are +exposed allowing allocation of these structs from Java code. The backing +storage for these Java classes is a direct java.nio Buffer. GlueGen +fully supports returning of pointers to C structs up to Java.</li> +</ul> +<h3 id="unique-features"><span id="SecUnique">Unique +Features</span></h3> +<p>GlueGen contains several unique features making it both a powerful +and easy-to-use tool.</p> +<ul> +<li>C structs are exposed as Java classes. The generated code for these +classes supports both 32-bit and 64-bit platforms.</li> +<li>C structs containing function pointers are exposed as Java classes +with methods. This makes it easy to interact with low-level C APIs such +as the AWT Native Interface (JAWT) from the Java programming language +level. +<ul> +<li>In this context, GlueGen automatically detects which argument to the +various function pointers indicates the "this" pointer, hiding it at the +Java level and passing it automatically.</li> +<li>GlueGen offers automatic handling of JNI-specific data types such as +<code>JNIEnv*</code> and <code>jobject</code>. The tool understands that +the <code>JNIEnv*</code> argument is implicit and that +<code>jobject</code> maps to java.lang.Object at the Java programming +language level. While this is most useful when binding JDK-internal APIs +such as the JAWT to Java, there may be other JNI libraries which expose +C functions taking these data types, and GlueGen can very easily bind to +them.</li> +</ul></li> +</ul> +<h3 +id="background-and-design-principles"><span id="SecBackground">Background +and Design Principles</span></h3> +<p>This section provides motivation for the design of the GlueGen tool +and is not necessary to understand how to use the tool.</p> +<p>There are many tools available for assisting in the autogeneration of +foreign function interfaces for various high-level languages. Only a few +examples include <a +href="http://alumni.media.mit.edu/~kbrussel/Header2Scheme/">Header2Scheme</a>, +an early tool allowing binding of a limited subset of C++ to the Scheme +programming language; <a href="http://www.swig.org/">SWIG</a>, a tool +released at roughly the same time as Header2Scheme which by now supports +binding C and C++ libraries to a variety of scripting languages; <a +href="http://www.jniwrapper.com/">JNIWrapper</a>, a commercial tool +automating the binding of C APIs to Java; and <a +href="http://web.archive.org/web/20070419183658/http://www.noodleglue.org/noodleglue/noodleglue.html">NoodleGlue</a>, +a recently-released tool automating the binding of C++ APIs to Java. +Other language-specific tools such as Perl's XS, Boost.Python and many +others exist.</p> +<p>GlueGen was designed with a few key principles in mind. The most +fundamental was to support binding of the lowest-level APIs on a given +platform up to the Java programming language. The intended goal, in the +context of the JOGL project, was to allow subsets of the Win32 and X11 +APIs to be exposed to Java, and to use those APIs to write the +behind-the-scenes OpenGL context creation and management code in Java +instead of C. This informed several other design goals:</p> +<ul> +<li>Avoid touching the C headers as much as possible. This makes it +easier to upgrade to a more recent version of the C API just by copying +in a new set of headers.</li> +<li>Avoid touching the generated glue code completely.</li> +<li>Avoid having to hand-write a lot of generated glue code. Instead, +handle many complex constructs automatically and provide sufficient +control over the glue code generation to avoid having to handwrite +certain native methods where one or two lines of tweaking would +suffice.</li> +<li>Support all C constructs in the parser and intermediate +representation. The rationale is that it is acceptable to cut corners in +the number of constructs supported in the Java binding, but not whether +the tool can internally represent it in its C type system. This design +goal implies starting with complete a ANSI C parser coupled with a +complete C type system.</li> +<li>As the tool is targetting the Java programming language, build the +tool in the Java programming language.</li> +</ul> +<p>In order to make the problem more tractable, support for binding C++ +to the Java programming language was not considered. C++ adds many +constructs over ANSI C which make it much more difficult to reason about +and to find a useful subset to support binding to Java. Additionally, it +seems that there are relatively few C++-specific libraries in general +use which could be usefully bound to Java, although this may be a matter +of opinion.</p> +<p>GlueGen was designed with the Java programming language in mind, but +is not necessarily restricted to generating glue code for the Java +language. The tool is divided into separate parse and code generation +phases, and the internal representation is fairly easy to iterate over. +The core driver of GlueGen may therefore be useful in producing other +tools which autogenerate foreign function interfaces to C libraries for +other languages.</p> +<h2 id="chapter-2---using-gluegen"><span id="Chapter2">Chapter 2 - Using +GlueGen</span></h2> +<h3 +id="acquiring-and-building-gluegen"><span id="SecAcquiring">Acquiring +and Building GlueGen</span></h3> +<p>The source code for GlueGen may be obtained by cloning the Git +repository:</p> +<pre><code> $git clone --recursive git://jogamp.org/srv/scm/gluegen.git gluegen</code></pre> +<p>To build GlueGen, cd into the gluegen/make folder and invoke ant.</p> +<pre><code> $ant clean all test</code></pre> +<p>Ant 1.8 or later and a Java 6 compatible JDK is required.</p> +<h4 id="common-build-problems"><span id="SecCommon">Common Build +Problems</span></h4> +<p><strong>CharScanner; panic: ClassNotFoundException: +com.jogamp.gluegen.cgram.CToken</strong><br /> +This occurs because ANTLR was dropped into the Extensions directory of +the JRE/JDK. On Windows and Linux, delete any ANTLR jars from +jre/lib/ext, and on Mac OS X, delete them from /Library/Java/Extensions. +Use the antlr.jar property in the build.xml to point to a JRE-external +location of this jar file.</p> +<h3 id="basic-operation"><span id="SecBasic">Basic Operation</span></h3> +<p>GlueGen can be run either as an executable jar file +(<code>java -jar gluegen.jar</code>; note +that antlr.jar must be in the same directory as gluegen.jar in order for +this invocation to work) or from within Ant as described in the +following section. When run from the command line, GlueGen accepts four +kinds of command-line arguments:</p> +<ul> +<li>-I<em>dir</em> (optional) adds <em>dir</em> to the include path. +Similarly to a C compiler or preprocessor, GlueGen scans a set of +directories to locate header files it encounters in +<code>#include</code> directives. Unlike most C preprocessors, however, +GlueGen has no default include path, so it is typically necessary to +supply at least one <code>-I</code> option on the command line in order +to handle any <code>#include</code> directives in the file being +parsed.</li> +<li>-E<em>emitterClassName</em> (optional) uses +<em>emitterClassName</em> as the fully-qualified name of the emitter +class which will be used by GlueGen to generate the glue code. The +emitter class must implement the +<code>com.jogamp.gluegen.GlueEmitter</code> interface. If this option is +not specified, a <code>com.jogamp.gluegen.JavaEmitter</code> will be +used by default.</li> +<li>-C<em>cfgFile</em> adds <em>cfgFile</em> to the list of +configuration files used to set up the chosen emitter. This is the means +by which a large number of options are passed in to the GlueGen tool and +to the emitter in particular. Configuration files are discussed more in +the following section.</li> +<li>[ filename | - ] selects the file or standard input from which +GlueGen should read the C header file for which glue code should be +generated. This must be the last command-line argument, and only one +filename argument is supported. To cause multiple header files to be +parsed, write a small .c file #including the multiple headers and point +GlueGen at the .c file.</li> +</ul> +<h3 id="running-gluegen-as-an-ant-task"><span id="SecAnt">Running +GlueGen as an Ant Task</span></h3> +<p>GlueGen can also be invoked as a subtask within Ant. In order to do +so, a path element should be defined as follows:</p> +<pre><code> <path id="gluegen.classpath"> + <pathelement location="${gluegen.jar}" /> + <pathelement location="${antlr.jar}" /> + </path></code></pre> +<p>where the <code>gluegen.jar</code> and <code>antlr.jar</code> +properties point to the respective jar files. A taskdef defining the +GlueGen task should then be specified as follows:</p> +<pre><code><taskdef name="gluegen" + classname="com.jogamp.gluegen.ant.GlueGenTask" + classpathref="gluegen.classpath" /></code></pre> +<p>At this point GlueGen may be invoked as follows:</p> +<pre><code><gluegen src="[header to parse]" + config="[configuration file]" + includeRefid="[dirset for include path]" + emitter="com.jogamp.gluegen.JavaEmitter"> + <classpath refid="gluegen.classpath" /> +</gluegen></code></pre> +<p>Please see the <a href="http://jogamp.org/jogl/">JOGL</a> and <a +href="http://jogamp.org/joal/">JOAL</a> build.xml files for concrete, +though non-trivial, examples of how to invoke GlueGen via Ant.</p> +<h3 id="jcpp"><span id="SecJCPP">JCPP</span></h3> +<p>GlueGen contains and uses the <a +href="https://jogamp.org/cgit/jcpp.git/about/">C preprocessor JCPP</a>, +see <a href="https://www.anarres.org/projects/jcpp/">original +homepage</a>.</p> +<p>Constant values intended for use by end users are defined in many C +libraries' headers using <code>#define</code>s rather than constant int +declarations. If the header would be processed by a full C preprocessor, +the <code>#define</code> statement's macro name become unavailable for +processing by the glue code generator. Using JCPP allows us to utilize +the <code>#define</code> macro names and values.</p> +<p>JCPP is largely an invisible part of the glue code generation +process. If GlueGen's output is not as expected and there is heavy use +of the C preprocessor in the header, run JCPP against the header +directly (JCPP takes simply the -I and filename arguments accepted by +GlueGen) and examine the output.</p> +<h3 id="stub-headers"><span id="SecStub">Stub Headers</span></h3> +<p>As much as is possible, GlueGen is intended to operate on unmodified +C header files, so that it is easy to upgrade the given C API being +bound to Java simply by dropping in a new set of header files. However, +most C headers contain references to standard headers like +<code>stdio.h</code>, and if this header is parsed by GlueGen, the tool +will automatically attempt to generate Java entry points for such +routines as <code>fread</code> and <code>fwrite</code>, among others. It +is impractical to exclude these APIs on a case by case basis. Therefore, +the suggested technique to avoid polluting the binding with these APIs +is to "stub out" the headers.</p> +<p>GlueGen searches the include path for headers in the order the +include directories were specified to the tool. Placing another +directory in front of the one in which the bulk of the headers are found +allows, for example, an alternative <code>stdio.h</code> to be inserted +which contains few or no declarations but which satisfies the need of +the dependent header to find such a file.</p> +<p>GlueGen uses a complete ANSI and GNU C parser written by John +Mitchell and Monty Zukowski from the set of grammars available for the +ANTLR tool by Terrence Parr. As a complete C parser, this grammar +requires all data types encountered during the parse to be fully +defined. Often a particular header will be included by another one in +order to pick up data type declarations rather than API declarations. +Stubbing out the header with a smaller one providing a "fake" type +declaration is a useful technique for avoiding the binding of +unnecessary APIs during the glue code process.</p> +<p>Here's an example from the JOGL glue code generation process. The +<code>glext.h</code> header defining OpenGL extensions references +<code>stddef.h</code> in order to pick up the <code>ptrdiff_t</code> +data type. We choose to not include the real stddef.h but instead to +swap in a stub header. The contents of this header are therefore as +follows:</p> +<pre><code> #if defined(_WIN64) typedef __int64 ptrdiff_t; #elif defined(__ia64__) || defined(__x86_64__) typedef long int ptrdiff_t; #else typedef int ptrdiff_t; - #endif - </pre> - <p> - This causes the ptrdiff_t data type to be defined appropriately for - the current architecture. It will be referenced during the glue code - generation and cause a Java value of the appropriate type (int or - long) to be used to represent it. - - </p> - <p> - - This is not the best example because it involves a data type which - changes size between 32- and 64-bit platforms, and there are otner - considerations to take into account in these situations (see the - section <a href="#Sec32">32- and 64-bit considerations</a>). Here's - another example, again from the JOGL source tree. JOGL binds the AWT - Native Interface, or JAWT, up to the Java programming language so that - the low-level code which binds OpenGL contexts to Windows device - contexts may be written in Java. The JDK's <code>jawt_md.h</code> on - the Windows platform includes <code>windows.h</code> to pick up the - definitions of data types such as <code>HWND</code> (window handle) - and <code>HDC</code> (handle to device context). However, it is - undesirable to try to parse the real <code>windows.h</code> just to - pick up these typedefs; not only does this header contain thousands of - unneeded APIs, but it also uses certain macro constructs not supported - by GlueGen's contained <a href="#SecJCPP">C preprocessor</a>. To avoid - these problems, a "stub" <code>windows.h</code> header is placed in - GlueGen's include path containing only the necessary typedefs: - </p> - <pre> - typedef struct _handle* HANDLE; + #endif</code></pre> +<p>This causes the ptrdiff_t data type to be defined appropriately for +the current architecture. It will be referenced during the glue code +generation and cause a Java value of the appropriate type (int or long) +to be used to represent it.</p> +<p>This is not the best example because it involves a data type which +changes size between 32- and 64-bit platforms, and there are otner +considerations to take into account in these situations (see the section +<a href="#Sec32">32- and 64-bit considerations</a>). Here's another +example, again from the JOGL source tree. JOGL binds the AWT Native +Interface, or JAWT, up to the Java programming language so that the +low-level code which binds OpenGL contexts to Windows device contexts +may be written in Java. The JDK's <code>jawt_md.h</code> on the Windows +platform includes <code>windows.h</code> to pick up the definitions of +data types such as <code>HWND</code> (window handle) and +<code>HDC</code> (handle to device context). However, it is undesirable +to try to parse the real <code>windows.h</code> just to pick up these +typedefs; not only does this header contain thousands of unneeded APIs, +but it also uses certain macro constructs not supported by GlueGen's +contained <a href="#SecJCPP">C preprocessor</a>. To avoid these +problems, a "stub" <code>windows.h</code> header is placed in GlueGen's +include path containing only the necessary typedefs:</p> +<pre><code> typedef struct _handle* HANDLE; typedef HANDLE HDC; - typedef HANDLE HWND; - </pre> - <p> - - Note that it is essential that the type being specified to GlueGen is - compatible at least in semantics with the real definition of the - HANDLE typedef in the real <code>windows.h</code>, so that during - compilation of GlueGen's autogenerated C code, when the real - <code>windows.h</code> is referenced by the C compiler, the - autogenerated code will compile correctly. - - </p> - <p> - - This example is not really complete as it also requires <a - href="#Sec32">consideration of the size of data types on 32- and - 64-bit platforms</a> as well as a discussion of how certain <a - href="#SecOpaque">opaque data types</a> are described to GlueGen and - exposed in its autogenerated APIs. Nonetheless, it illustrates at a - basic level why using a stub header is necessary and useful in certain - situations. - - </p> - - <h3><a name="Sec32">32- and 64-bit Considerations</a></h3> - - <p> - - When binding C functions to the Java programming language, it is - important that the resulting Java code support execution on a 64-bit - platform if the associated native methods are compiled appropriately. - In other words, the public Java API should not change if the - underlying C data types change to another data model such as LP64 (in - which longs and pointers become 64-bit). - - </p> - <p> - - GlueGen internally maintains two descriptions of the underlying C data - model: one for 32-bit architectures and one for 64-bit architectures. - These machine descriptions are used when deciding the mapping between - integral C types such as int and long and the corresponding Java - types, as well as when laying out C structs for access by the Java - language. For each autogenerated C struct accessor, both a 32-bit and - 64-bit variant are generated behind the scenes, ensuring that the - resulting Java code will run correctly on both 32-bit and 64-bit - architectures. - - </p> - <p> - - When generating the main class containing the bulk of the method - bindings, GlueGen uses the 64-bit machine description to map C data - types to Java data types. This ensures that the resulting code will - run properly on 64-bit platforms. Note that it also generally means - that C <code>long</code>s will be mapped to Java <code>long</code>s, - since an LP64 data model is assumed. - - </p> - <p> - - If <a href="#SecOpaque">Opaque directives</a> are used to cause a - given C integer or pointer data type to be mapped directly to a Java - primitive type, care should be taken to make sure that the Java - primitive type is wide enough to hold all of the data even on 64-bit - platforms. Even if the data type is defined in the header file as - being only a 32-bit C integer, if there is a chance that on a 64-bit - platform the same header may define the data type as a 64-bit C - integer or long, the Opaque directive should map the C type to a Java - long. - - </p> - - <h3><a name="SecOpaque">Opaque Directives</a></h3> - - <p> - - Complex header files may contain declarations for certain data types - that are either too complex for GlueGen to handle or unnecessarily - complex from the standpoint of glue code generation. In these - situations a stub header may be used to declare a suitably compatible - typedef for the data type. An <a href="#Opaque">Opaque</a> directive - can be used to map the resulting typedef to a Java primitive type if - it is undesirable to expose it as a full-blown Java wrapper class. - - </p> - <p> - - GlueGen hashes all typedefs internally down to their underlying - primitive type. (This is probably not really correct according to the - C type system, but is correct enough from a glue code generation - standpoint, where if the types are compatible they are considered - equivalent.) This means that if the parser encounters - </p> - <pre> - typedef void* LPVOID; - </pre> - <p> - - then an Opaque directive stating - </p> - <pre> - Opaque long LPVOID - </pre> - <p> - will cause all <code>void*</code> or <code>LPVOID</code> arguments in - the API to be mapped to Java longs, which is almost never desirable. - Unfortunately, it is not currently possible to distinguish between the - LPVOID typedef and the underlying <code>void*</code> data type in this - situation. - - </p> - <p> - - A similar problem occurs for other data types for which Opaque - directives may be desired. For example, a Windows HANDLE equates to a - typedef to <code>void*</code>, but performing this typedef in a stub - header and then adding the Opaque directive - </p> - <pre> - Opaque long HANDLE - </pre> - <p> - will cause all void* arguments to be exposed as Java longs instead of - Buffers, which is again undesirable. Attempting to work around the - problem by typedef'ing HANDLE to an integral type, as in: - </p> - <pre> - typedef long HANDLE; - </pre> - <p> - may itself have problems, because GlueGen will assume the two integral - types are compatible and not perform any intermediate casts between - HANDLE and jlong in the autogenerated C code. (When casting between a - pointer type and a JNI integral type such as jlong in C code, GlueGen - automatically inserts casts to convert the pointer first to an - "intptr_t" and then to the appropriate JNI type, in order to silence - compiler warnings and/or errors.) - - </p> - <p> - - What is desired is to produce a new type name distinct from all others - but still compatible with the pointer semantics of the original type. - Then an Opaque directive can be used to map the new type name to, for - example, a Java long. - - </p> - <p> - - To implement this in the context of the HANDLE example, the following - typedef may be inserted into the stub header: - </p> - <pre> - typedef struct _handle* HANDLE; - </pre> - <p> - This uses a pointer to an anonymous struct name to produce a new - pointer type. This is legal ANSI C and is supported by GlueGen's - parser without having seen a declaration for "struct _handle". - Subsequently, an Opaque directive can be used to map the HANDLE data - type to a Java long: - </p> - <pre> - Opaque long HANDLE - </pre> - <p> - Now HANDLEs are exposed to Java as longs as desired. A similar - technique is used to expose XIDs on the X11 platform as Java longs. - - </p> - - - <h3><a name="SecSubstitution">Argument Name Substitution</a></h3> - - <p> - - Certain configuration file directives allow the insertion of Java or C - code at various places in the generated glue code, to both eliminate - the need to hand-edit the generated glue code as well as to minimize - the hand-writing of glue code, which sidesteps the GlueGen process. In - some situations the inserted code may reference incoming arguments to - compute some value or perform some operation. Examples of directives - supporting this substitution include <a - href="#ReturnValueCapacity">ReturnValueCapacity</a> and <a - href="#ReturnedArrayLength">ReturnedArrayLength</a>. - - </p> - <p> - - The expressions in these directives may contain Java MessageFormat - expressions like <code>{0}</code> which refer to the incoming argument - names to the function. <code>{0}</code> refers to the first incoming - argument. - - </p> - <p> - - Strongly-typed C primitive pointers such as <code>int*</code>, which - ordinarily expand to overloaded Java methods taking - e.g. <code>int[]</code> as well as <code>IntBuffer</code>, present a - problem. The expansion to <code>int[] arr</code> also generates an - <code>int arr_offset</code> argument to be able to pass a pointer into - the middle of the array down to C. To allow the same MessageFormat - expression to be used for both cases, the subsitution that occurs when - such a primitive array is referenced is the string <code>arr, - arr_offset</code>; in other words, the subtituted string contains a - comma. This construct may be used in the following way: the code being - manually inserted may itself contain a method call taking - e.g. <code>{3}</code> (the incoming argument index of the primitive - array or buffer). The user should supply two overloaded versions of - this method, one taking a strongly-typed Buffer and one taking e.g. an - <code>int[] arr</code> and <code>int arr_offset</code> argument. The - implementation of <code>RangeCheck</code>s for primitive arrays and - strongly-typed buffers uses this construct. - - </p> - <p> - - It should be noted that in the autogenerated C code the offset - argument is expressed in bytes while at the Java level it is expressed - in elements. Most uses of GlueGen will probably not have to refer to - the primitive array arguments in C code so this slight confusion - should be minor. - - </p> - - - <h3><a name="SecConfiguration">Configuration File Directives</a></h3> - - <p> - - In addition to the C headers, GlueGen requires a certain amount of - metadata in the form of configuration files in order to produce its - glue code. There are three basic reasons for this: first, GlueGen must - be informed into which Java classes the C methods are to be bound; - second, there are many configuration options for the generated glue - code, and passing them all on the command line is infeasible; and - third, there are ambiguities in many constructs in the C programming - language which must be resolved before a Java binding can be produced. - - </p> - <p> - - The contents of the configuration file are dependent on the class of - emitter specified to GlueGen. Currently there are three built-in - emitter classes: JavaEmitter, which produces a basic, static Java - binding of C functions; ProcAddressEmitter, which extends JavaEmitter - by calling the underlying C functions through function pointers, - resulting in more dynamic behavior and supporting C APIs with optional - functionality; and GLEmitter, which specializes ProcAddressEmitter to - support some OpenGL-specific constructs. The GLEmitter will be ignored - in this manual as it is specialized for JOGL and provides very little - additional functionality beyond the ProcAddressEmitter. The - JavaEmitter and ProcAddressEmitter support many options in their - configuration files. As the ProcAddressEmitter is a subclass of - JavaEmitter, all of the constructs in the JavaEmitter's configuration - files are also legal in the ProcAddressEmitter's configuration files. - - </p> - <p> - - The configuration files have a very simple line-by-line structure, and - are parsed by a very rudimentary, hand-written parser. Each - non-whitespace and non-comment line (note: comment lines begin with - '#') contains a directive like <code>Package</code>, - <code>Style</code> or <code>JavaClass</code> followed by arguments to - that directive. There are a certain set of directives that are - required for any code generation; others are optional and their - omission results in some default behavior. Directives are - case-insensitive. - - </p> - <p> - - The following is an exhaustive list of the options currently supported - by each of these emitters' configuration files. It is difficult to see - exactly how to use the tool based simply on these descriptions, so the - <a href="#Chapter3">examples</a> may be more helpful in seeing exactly - how to structure a configuration file for proper glue code generation. - - </p> - - - <h4><a name="SecJavaEmitter">JavaEmitter Configuration</a></h4> - - <p> - - Note that only a very few of the following directives are specified as - being "required" rather than "optional"; these indicate the minimal - directives needed for a valid configuration file to begin to get glue - code to be produced. In general, these are <a - href="#Package">Package</a>, <a href="#ImplPackage">ImplPackage</a>, - <a href="#JavaClass">JavaClass</a>, <a - href="#ImplJavaClass">ImplJavaClass</a>, and <a - href="#Style">Style</a>. Other directives such as <a - href="#NioDirectOnly">NioDirectOnly</a> are required in some - circumstances for the glue code to be correct, and some such as <a - href="#ReturnedArrayLength">ReturnedArrayLength</a>, <a - href="#ReturnValueCapacity">ReturnValueCapacity</a>, and <a - href="#ReturnValueLength">ReturnValueLength</a> should be specified in - some situations in order for certain return values to be useful at the - Java level. - - </p> - <p> - - The following directives are specified in alphabetical order, although - this is not necessarily the best semantic order. - - </p> - - <dl> - - - <dt><strong><a name="AccessControl">AccessControl</a></strong></dt> - <dd> Syntax: <code>AccessControl [method name] [ PUBLIC | PROTECTED | PRIVATE | PACKAGE_PRIVATE ]</code> <br/> - - (optional) Controls the access control of a certain Java method - corresponding to a C function. The access control of all APIs defaults - to public. This is useful when using the C binding of a particular - function only as one implementation strategy of the real public API - and using <a href="#CustomJavaCode">CustomJavaCode</a> to write the - exposed API. In this case is most useful in conjunction with <a - href="#RenameJavaMethod">RenameJavaMethod</a>. - </dd> - - - <dt><strong><a name="ArgumentIsString">ArgumentIsString</a></strong></dt> - <dd> Syntax: <code>ArgumentIsString [function name] - [indices...]</code> where the first argument index is 0 <br/> - - (optional) For a C function with one or more outgoing - <code>char*</code> (or compatible data type) arguments, indicates that - those arguments are semantically null-terminated C strings rather than - arbitrary arrays of bytes. The generated glue code will be modified to - emit those arguments as java.lang.String objects rather than - <code>byte[]</code> or <code>ByteBuffer</code>. - </dd> - - <dt><strong><a name="ArgumentIsPascalString">ArgumentIsPascalString</a></strong></dt> - <dd> Syntax: <code>ArgumentIsPascalString [function name] - [indice-tuples...]</code>, with each tuple being the argument-index for the '<code>int length</code>' - and the '<code>char* value</code>' argument with index 0 for the the first argument<br/> - - (optional) For a C function with one or more outgoing - '<code>int length</code>' and '<code>char* value</code>' (or compatible data type) arguments, - indicates that those arguments are semantically non-null-terminated Pascal strings rather than - null-terminated C strings or arbitrary arrays of bytes. The generated glue code will be modified to - emit those arguments as java.lang.String objects rather than - <code>byte[]</code> or <code>ByteBuffer</code>. - </dd> - - <dt><strong><a name="ClassJavadoc">ClassJavadoc</a></strong></dt> - <dd> Syntax: <code>ClassJavadoc [class name] [code...]</code> <br/> - - (optional) Causes the specified line of code to be emitted in the - appropriate place in the generated code to become the per-class - Javadoc for the specified class. By default GlueGen produces no - Javadoc for its generated classes, so this is the mechanism by which a - user can emit Javadoc for these classes. The specified Javadoc - undergoes no transformation by GlueGen, so the initial - <code>/**</code> and trailing <code>*/</code> must be included in the - correct place. Each line of Javadoc is emitted in the order - encountered during parsing of the configuration files. - </dd> - - <dt><strong><a name="CustomCCode">CustomCCode</a></strong></dt> - <dd>Syntax: <code>CustomCCode [code...]</code> <br/> - - (optional) Causes the specified line of C code to be emitted into the - generated native code for the implementing class. Currently there is - no way (and no real need) to be able to emit custom C code into any - other generated .c file, so the class name in the <a - href="#CustomJavaCode">CustomJavaCode</a> directive is omitted. - </dd> - - <dt><strong><a name="CustomJavaCode">CustomJavaCode</a></strong></dt> - <dd>Syntax: <code>CustomJavaCode [class name] [code...]</code> <br/> - - (optional) Causes the specified line of Java code to be emitted into - the specified generated Java class. Can be used to emit code into any - generated class: the public interface, the implementing class, the - sole concrete class (in the case of the AllStatic <a - href="#Style">Style</a>), or any of the Java classes corresponding to - referenced C structs in the parsed headers. This usage is somewhat - verbose, and the <a href="#IncludeAs">IncludeAs</a> directive provides - a more concise way of including large bodies of Java code into the - generated code. - </dd> - - <dt><strong><a name="CustomJNICode">CustomJNICode</a></strong></dt> - <dd>Syntax: <code>CustomJNICode [class name] [code...]</code> <br/> - - (optional) Causes the specified line of C code to be emitted into - the generated JNI code related of specified Java class. Can be used - to emit JNI code related of any generated class: the public interface, - the implementing class, the sole concrete class (in the case of - the AllStatic <a href="#Style">Style</a>), or any of the Java - classes corresponding to referenced C structs in the parsed headers. - This usage is somewhat verbose, and the <a href="#IncludeAs">IncludeAs</a> - directive provides a more concise way of including large bodies of - C code into the generated code. - </dd> - - <dt><strong><a name="EmitStruct">EmitStruct</a></strong></dt> - <dd>Syntax: <code>EmitStruct [C struct type name]</code> <br/> - - (optional) Forces a Java class to be emitted for the specified C - struct. Normally only those structs referenced directly by the parsed - C APIs have corresponding Java classes emitted. - </dd> - - <dt><strong><a name="GlueGenRuntimePackage">GlueGenRuntimePackage</a></strong></dt> - <dd>Syntax: <code>GlueGenRuntimePackage [package name, like com.jogamp.gluegen.runtime]</code> <br/> - - (optional) Changes the package in which the generated glue code - expects to find its run-time helper classes (like Buffers, CPU, - StructAccessor). Defaults to <code>com.jogamp.gluegen.runtime</code> (no - quotes). This is useful if you want to bundle the runtime classes in - your application without the possibility of interfering with other - versions elsewhere in the system. - </dd> - - <dt><strong><a name="ExtendedInterfaceSymbolsIgnore">ExtendedInterfaceSymbolsIgnore</a></strong></dt> - <dd>Syntax: <code>ExtendedInterfaceSymbolsIgnore [Java file]</code> <br/> - - (optional) Causes all autogenerated Java interface ignore - all symbols from interface declared inside named Java source - file.<br /> - - This directive can be used with <a href="#Extends">Extends</a> directive.<br /> - - Cf here for more information : - <a href="../GlueGen_Mapping.html#oo-style-example">GlueGen_Mapping</a> - </dd> - - <dt><strong><a name="ExtendedInterfaceSymbolsOnly">ExtendedInterfaceSymbolsOnly</a></strong></dt> - <dd>Syntax: <code>ExtendedInterfaceSymbolsOnly [Java file]</code> <br/> - - (optional) Causes all autogenerated Java interface generate - only symbols from interface declared inside named Java source - file.<br /> - - This directive can be used with <a href="#Extends">Extends</a> directive.<br /> - - Cf here for more information : - <a href="../GlueGen_Mapping.html#oo-style-example">GlueGen_Mapping</a> - </dd> - - <dt><strong><a name="ExtendedImplementationSymbolsIgnore">ExtendedImplementationSymbolsIgnore</a></strong></dt> - <dd>Syntax: <code>ExtendedImplementationSymbolsIgnore [Java file]</code> <br/> - - (optional) Causes all autogenerated Java classes ignore - all symbols from interface or classe declared inside named - Java source file.<br /> - - This directive can be used with <a href="#ParentClass">ParentClass</a> directive.<br /> - - Cf here for more information : - <a href="../GlueGen_Mapping.html#oo-style-example">GlueGen_Mapping</a> - </dd> - - <dt><strong><a name="ExtendedImplementationSymbolsOnly">ExtendedImplementationSymbolsOnly</a></strong></dt> - <dd>Syntax: <code>ExtendedImplementationSymbolsOnly [Java file]</code> <br/> - - (optional) Causes all autogenerated Java classes generate - only symbols from interface or classe declared inside named - Java source file.<br /> - - This directive can be used with <a href="#ParentClass">ParentClass</a> directive.<br /> - - Cf here for more information : - <a href="../GlueGen_Mapping.html#oo-style-example">GlueGen_Mapping</a> - </dd> - - <dt><strong><a name="ExtendedIntfAndImplSymbolsIgnore">ExtendedIntfAndImplSymbolsIgnore</a></strong></dt> - <dd>Syntax: <code>ExtendedIntfAndImplSymbolsIgnore [Java file]</code> <br/> - - (optional) Causes all autogenerated Java interface and classes ignore - all symbols from interface or classe declared inside named - Java source file.<br /> - - This directive can be used with <a href="#Extends">Extends</a> or - <a href="#ParentClass">ParentClass</a> directives.<br /> - - Cf here for more information : - <a href="../GlueGen_Mapping.html#oo-style-example">GlueGen_Mapping</a> - </dd> - - <dt><strong><a name="ExtendedIntfAndImplSymbolsOnly">ExtendedIntfAndImplSymbolsOnly</a></strong></dt> - <dd>Syntax: <code>ExtendedIntfAndImplSymbolsOnly [Java file]</code> <br/> - - (optional) Causes all autogenerated Java interface and classes generate - only symbols from interface or classe declared inside named - Java source file.<br /> - - This directive can be used with <a href="#Extends">Extends</a> or - <a href="#ParentClass">ParentClass</a> directives.<br /> - - Cf here for more information : - <a href="../GlueGen_Mapping.html#oo-style-example">GlueGen_Mapping</a> - </dd> - - <dt><strong><a name="Extends">Extends</a></strong></dt> - <dd>Syntax: <code>Extends [Java interface name] [interface name to extend] </code> <br/> - - (optional) Causes the specified autogenerated Java interface to - declare that it extends another one. This directive may only be - applied to autogenerated interfaces, not concrete classes. For - concrete classes, use <a href="#Implements">Implements</a> - directive or <a href="#ParentClass">ParentClass</a> directive. - </dd> - - <dt><strong><a name="HierarchicalNativeOutput">HierarchicalNativeOutput</a></strong></dt> - <dd>Syntax: <code>HierarchicalNativeOutput true</code> <br/> - - (optional) If "true", makes subdirectories for the generated native - code matching the package names of the associated classes. This is - typically not needed (or desired, as it complicates the compilation - process for this native code) and defaults to false. - </dd> - - <dt><strong><a name="Ignore">Ignore</a></strong></dt> - <dd> Syntax: <code>Ignore [regexp]</code> <br/> - - (optional) Ignores one or more functions or data types matching the - regexp argument which are encountered during parsing of the C - headers. By default GlueGen will emit all encountered C functions as - well as Java classes corresponding to all C structs referenced by - those functions. Related directives are <a - href="#IgnoreNot">IgnoreNot</a>, <a href="#Unignore">Unignore</a> and - <a href="#EmitStruct">EmitStruct</a>. - </dd> - - <dt><strong><a name="IgnoreField">IgnoreField</a></strong></dt> - <dd> Syntax: <code>IgnoreField [struct type name] [field name]</code> - <br/> - - (optional) Causes the specified field of the specified struct type - to be ignored during code generation, typically because it is too - complex for GlueGen to handle. - </dd> - - <dt><strong><a name="IgnoreNot">IgnoreNot</a></strong></dt> - <dd> Syntax: see <a href="#Ignore">Ignore</a>. - - (optional) Similar to the <a href="#Ignore">Ignore</a> directive, but - evaluates the negation of the passed regexp when deciding whether to - ignore the given function or data type. The <a - href="#Unignore">Unignore</a> mechanism may be used with IgnoreNot as - well. NOTE: the IgnoreNot mechanism may ultimately turn out to be - superfluous; the authors do not have sufficient experience with - regular expressions to know whether general negation of a regexp is - possible. Feedback in this area would be appreciated. - </dd> - - <dt><strong><a name="Implements">Implements</a></strong></dt> - <dd> Syntax: <code>Implements [Java class name] [interface name to - implement]</code> <br/> - - (optional) Causes the specified autogenerated Java concrete class to - declare that it implements the specified interface. This directive may - only be applied to autogenerated concrete classes, not interfaces. For - interfaces, use the <a href="#Extends">Extends</a> directive. - </dd> - - <dt><strong><a name="ImplJavaClass">ImplJavaClass</a></strong></dt> - <dd> Syntax: <code>ImplJavaClass [class name]</code> <br/> - - (optional) Specifies the name of the typically non-public, - implementation Java class which contains the concrete Java and native - methods for the glue code. If the emission style is AllStatic, there - is no distinction between the public and implementation class and - ImplJavaClass should not be specified. Otherwise, if the ImplJavaClass - is unspecified, it defaults to the JavaClass name plus "Impl". (If - both are unspecified in this configuration, an error is reported.) See - also <a href="#JavaClass">JavaClass</a>. - </dd> - - <dt><strong><a name="ImplPackage">ImplPackage</a></strong></dt> - <dd> Syntax: <code>ImplPackage [package name]</code> <br/> - - (optional) Specifies the package name into which the implementing - class containing the concrete Java and native methods will be emitted, - assuming an emission style of InterfaceAndImpl or ImplOnly. If - AllStatic, there is no separate implementing class from the public - interface. If the emission style is not AllStatic and the ImplPackage - is not specified, it defaults to the Package plus ".impl". See also <a - href="#Package">Package</a>. - </dd> - - <dt><strong><a name="Import">Import</a></strong></dt> - <dd>Syntax: <code>Import [package name]</code> (no trailing semicolon) - <br/> - - (optional) Adds an import statement at the top of each generated Java - source file. - </dd> - - <dt><strong><a name="Include">Include</a></strong></dt> - <dd> Syntax: <code>Include [filename]</code> <br/> - - (optional) Causes another configuration file to be read at the current - point in parsing the current configuration file. The filename argument - may be either absolute or relative; in the latter case it is specified - relative to the location of the current configuration file. - </dd> - - <dt><strong><a name="IncludeAs">IncludeAs</a></strong></dt> - <dd>Syntax: <code>IncludeAs [prefix tokens] [filename]</code> <br/> - - (optional) Similar to the <a href="#Include">Include</a> directive, - but prepends the specified prefix tokens on to every line of the file - to be read. The last token parsed is the name of the file to be - read. This allows, for example, <a - href="#CustomJavaCode">CustomJavaCode</a> to be stored as Java source - rather than in the configuration file; in this example the - configuration file might contain <code>IncludeAs CustomJavaCode - MyClass MyClass-CustomJavaCode.java</code>. - </dd> - - <dt><strong><a name="JavaClass">JavaClass</a></strong></dt> - <dd> Syntax: <code>JavaClass [class name]</code> <br/> - - (optional / required) Specifies the name of the public, - non-implementation Java class or interface into which the glue code - will be generated. If the emission style is not ImplOnly, the - JavaClass directive is required. See also <a - href="#ImplJavaClass">ImplJavaClass</a>. - </dd> - - <dt><strong><a name="JavaEpilogue">JavaEpilogue</a></strong></dt> - <dd>Syntax: <code>JavaEpilogue [C function name] [code...]</code> <br/> - - (optional) Adds the specified code as an epilogue in the Java method - for the specified C function; this code is run after the underlying C - function has been called via the native method but before any result - is returned. As in the <a - href="#ReturnedArrayLength">ReturnedArrayLength</a> and other - directives, <a href="#SecSubstitution">argument name - substitution</a> is performed on MessageFormat expressions in the - specified code. See also <a href="#JavaPrologue">JavaPrologue</a>. - </dd> - - <dt><strong><a name="JavaOutputDir">JavaOutputDir</a></strong></dt> - <dd> Syntax: <code>JavaOutputDir [directory name]</code> <br/> - - (optional) Specifies the root directory into which the emitted - Java code will be produced. Subdirectories for the packages of the - associated Java classes will be automatically created. If unspecified, - defaults to the current working directory. - </dd> - - <dt><strong><a name="JavaPrologue">JavaPrologue</a></strong></dt> - <dd> Syntax: <code>JavaPrologue [C function name] [code...]</code> - <br/> - - (optional) Adds the specified code as a prologue in the Java method - for the specified C function; this code is run before the underlying C - function is called via the native method. As in the <a - href="#ReturnedArrayLength">ReturnedArrayLength</a> and other - directives, <a href="#SecSubstitution">argument name - substitution</a> is performed on MessageFormat expressions in the - specified code. See also <a href="#JavaEpilogue">JavaEpilogue</a>. - </dd> - - <dt><strong><a name="ManuallyImplement">ManuallyImplement</a></strong></dt> - <dd> Syntax: <code>ManuallyImplement [function name]</code> <br/> - - (optional) Indicates to GlueGen to not produce a method into the - implementing class for the specified C function; the user must provide - one via the <a href="#CustomJavaCode">CustomJavaCode</a> directive. If - the emission style is InterfaceAndImpl or InterfaceOnly, a public - method will still be generated for the specified function. - </dd> - - <dt><strong><a name="MaxOneElement">MaxOneElement</a></strong></dt> - <dd> Syntax: <code>MaxOneElement [function name]</code> <br/> - - (optional) Indicates that the specified C function/attribute - which returns a single element instead a ByteBuffer if signature - or compatible type actually returns a pointer like int* but isn't an - array.<br /> - - Cf here for more information : - <a href="../GlueGen_Mapping.html#gluegen-struct-settings">GlueGen_Mapping</a> - </dd> - - <dt><strong><a name="NativeOutputDir">NativeOutputDir</a></strong></dt> - <dd> Syntax: <code>NativeOutputDir [directory name]</code> <br/> - - (optional) Specifies the root directory into which the emitted JNI - code will be produced. If unspecified, defaults to the current working - directory. See also <a - href="#HierarchicalNativeOutput">HierarchicalNativeOutput</a>. - </dd> - - <dt><strong><a name="NioDirectOnly">NioDirectOnly</a></strong></dt> - <dd> Syntax: <code>NioDirectOnly [function name]</code> <br/> - - (required when necessary) When passing a pointer down to a C API, it - is semantically undefined whether the underlying C code expects to - treat that pointer as a persistent pointer, living past the point of - return of the function call, or whether the pointer is used only - during the duration of the function call. For APIs taking C primitive - pointers such as <code>void*</code>, <code>float*</code>, etc., - GlueGen will typically generate up to two overloaded Java methods, one - taking a <code>Buffer</code> or <code>Buffer</code> subclass such as - <code>FloatBuffer</code>, and one taking a primitive array such as - <code>float[]</code>. (In the case of <code>void*</code> outgoing - arguments, GlueGen produces only one variant taking a Buffer.) - Normally the generated glue code accepts either a "direct" or - non-"direct" buffer (according to the New I/O APIs) as argument. - However, if the semantics of the C function are that it either expects - to hold on to this pointer past the point of the function call, or if - it can block while holding on to the pointer, the - <code>NioDirectOnly</code> directive <strong>must</strong> be - specified for this C function in order for the generated glue code to - be correct. Failing to observe this requirement may cause JVM hangs or - crashes. - </dd> - - <dt><strong><a name="Opaque">Opaque</a></strong></dt> - <dd> Syntax: <code>Opaque [Java primitive data type] [C data - type]</code> <br/> - - (optional) Causes a particular C data type to be exposed in opaque - form as a Java primitive type. This is most useful for certain pointer - types for which it is not desired to generate full Java classes but - instead expose them to Java as e.g. <code>long</code>s. It is also - useful for forcing certain integral C data types to be exposed as e.g. - <code>long</code> to Java to ensure 64-bit cleanliness of the - generated glue code. See the <a href="#Chapter3">examples</a>. The C - data type may be a multiple-level pointer type; for example - <code>Opaque long void**</code>. Note that it is not currently - supported to make a given data type opaque for just a few functions; - the Opaque directive currently applies to all C functions in the - headers being parsed. This means that sweeping Opaque declarations - like <code>Opaque long void*</code> will likely have unforseen and - undesirable consequences. - </dd> - - <dt><strong><a name="Package">Package</a></strong></dt> - <dd> Syntax: <code>Package [package name]</code> (no trailing - semicolon) <br/> - - (optional / required) Specifies the package into which the public - interface or class for the autogenerated glue code will be - generated. Required whenever the emission style is not ImplOnly. See - also <a href="#ImplPackage">ImplPackage</a>. - </dd> - - <dt><strong><a name="ParentClass">ParentClass</a></strong></dt> - <dd>Syntax: <code>ParentClass [Java class name] [class name to extend] </code> <br/> - - (optional) Causes the specified autogenerated Java classe to - declare that it extends another one. This directive may only be - applied to autogenerated classes, not interface. For - interfaces, use the <a href="#Extends">Extends</a> directive. - </dd> - - <dt><strong><a name="RangeCheck">RangeCheck</a></strong></dt> - <dd> Syntax: <code>RangeCheck [C function name] [argument number] [expression]</code> <br/> - - (optional) Causes a range check to be performed on the specified array - or Buffer argument of the specified autogenerated Java method. This - range check ensures, for example, that a certain number of elements - are remaining in the passed Buffer, knowing that the underlying C API - will access no more than that number of elements. For range checks - that should be expressed in terms of a number of bytes rather than a - number of elements, see the <a - href="#RangeCheckBytes">RangeCheckBytes</a> directive. As in the <a - href="#ReturnedArrayLength">ReturnedArrayLength</a> and other - directives, <a href="#SecSubstitution">argument name substitution</a> - is performed on MessageFormat expressions. - </dd> - - <dt><strong><a name="RangeCheckBytes">RangeCheckBytes</a></strong></dt> - <dd> Syntax: <code>RangeCheckBytes [C function name] [argument number] - [expression]</code> <br/> - - (optional) Same as the <a href="#RangeCheck">RangeCheck</a> directive, - but the specified expression is treated as a minimum number of bytes - remaining rather than a minimum number of elements remaining. This - directive may not be used with primitive arrays. - </dd> - - <dt><strong><a name="RenameJavaMethod">RenameJavaMethod</a></strong></dt> - <dd> Syntax: <code>RenameJavaMethod [from name] [to name]</code> <br/> - - (optional) Causes the specified C function to be emitted under a - different name in the Java binding. This is most useful in conjunction - with the <a href="#AccessControl">AccessControl</a> directive when the - C function being bound to Java is only one potential implementation of - the public API, or when a considerable amount of Java-side custom code - is desired to wrap the underlying C native method entry point. - </dd> - - <dt><strong><a name="RenameJavaType">RenameJavaType</a></strong></dt> - <dd> Syntax: <code>RenameJavaType [from name] [to name]</code> <br/> - - (optional) Causes the specified C struct to be exposed as a Java class - under a different name. This only applies to autogenerated classes - corresponding to C structs encountered during glue code generation; - full control is provided over the name of the top-level classes - associated with the set of C functions via the <a - href="#JavaClass">JavaClass</a> and <a - href="#ImplJavaClass">ImplJavaClass</a> directives. - </dd> - - <dt><strong><a name="ReturnedArrayLength">ReturnedArrayLength</a></strong></dt> - <dd> Syntax: <code>ReturnedArrayLength [C function name] - [expression]</code> where <code>expression</code> is a legal Java - expression with MessageFormat specifiers such as "{0}". These - specifiers will be replaced in the generated glue code with the - incoming argument names where the first argument to the method is - numbered 0. See the section on <a href="#SecSubstitution"> argument - name substitution</a>.<br/> - - (optional) For a function returning a compound C pointer type such as - an <code>XVisualInfo*</code>, indicates that the returned pointer is - to be treated as an array and specifies the length of the returned - array as a function of the arguments passed to the function. Note that - this directive differs subtly from <a - href="#ReturnValueCapacity">ReturnValueCapacity</a> and - ReturnValueLength. It is also sometimes most useful in conjunction - with the <a - href="#TemporaryCVariableDeclaration">TemporaryCVariableDeclaration</a> - and TemporaryCVariableAssignment directives. - </dd> - - <dt><strong><a name="ReturnsString">ReturnsString</a></strong></dt> - <dd> Syntax: <code>ReturnsString [function name]</code> <br/> - - (optional) Indicates that the specified C function which returns a - <code>char*</code> or compatible type actually returns a - null-terminated C string which should be exposed as a - java.lang.String. NOTE: currently does not properly handle the case - where this storage needs to be freed by the end user. In these - situations the data should be returned as a direct ByteBuffer, the - ByteBuffer converted to a String using custom Java code, and the - ByteBuffer freed manually using another function bound to Java. - </dd> - <dt><strong><a name="ReturnsStringOnly">ReturnsStringOnly</a></strong></dt> - <dd> Syntax: <code>ReturnsStringOnly [function name]</code> <br/> - - (optional) Like the <a href="#ReturnsString">ReturnsString</a> instruction, - but without the classic getters and setters with ByteBuffer.<br /> - - Cf here for more information : - <a href="../GlueGen_Mapping.html#gluegen-struct-settings">GlueGen_Mapping</a> - </dd> - <dt><strong><a name="ReturnValueCapacity">ReturnValueCapacity</a></strong></dt> - <dd> Syntax: <code>ReturnValueCapacity [C function name] - [expression]</code> <br/> - - (optional) Specifies the capacity of a java.nio <code>Buffer</code> or - subclass wrapping a C primitive pointer such as <code>char*</code> or - <code>float*</code> being returned from a C function. Typically - necessary in order to properly use such pointer return results from - Java. As in the <a href="#ReturnedArrayLength">ReturnedArrayLength</a> - directive, <a href="#SecSubstitution">argument name substitution</a> - is performed on MessageFormat expressions. - </dd> - - <dt><strong><a name="ReturnValueLength">ReturnValueLength</a></strong></dt> - <dd> Syntax: <code>ReturnValueLength [C function name] [expression]</code> <br/> - - (optional) Specifies the length of a returned array of pointers, - typically to C structs, from a C function. This differs from the <a - href="#ReturnedArrayLength">ReturnedArrayLength</a> directive in the - pointer indirection to the array elements. The <a - href="#ReturnedArrayLength">ReturnedArrayLength</a> directive handles - slicing up of a linear array of structs, while the ReturnValueLength - directive handles boxing of individual elements of the array (which - are pointers) in to the Java class which wraps that C struct type. See - the <a href="#Chapter3">examples</a> for a concrete example of usage. - As in the <a href="#ReturnedArrayLength">ReturnedArrayLength</a> - directive, <a href="#SecSubstitution">argument name substitution</a> - is performed on MessageFormat expressions. - </dd> - - <dt><strong><a name="RuntimeExceptionType">RuntimeExceptionType</a></strong></dt> - <dd> Syntax: <code>RuntimeExceptionType [class name]</code> <br/> - - (optional) Specifies the class name of the exception type which should - be thrown when run-time related exceptions occur in the generated glue - code, for example if a non-direct Buffer is passed to a method for - which <a href="#NioDirectOnly">NioDirectOnly</a> was - specified. Defaults to <code>RuntimeException</code>. - </dd> - - <dt><strong><a name="StructPackage">StructPackage</a></strong></dt> - <dd> Syntax: <code>StructPackage [C struct type name] [package - name]</code>. Package name contains no trailing semicolon. <br/> - - (optional) Indicates that the specified Java class corresponding to - the specified C struct should be placed in the specified package. By - default, these autogenerated Java classes corresponding to C structs - are placed in the main package (that defined by <a - href="#PackageName">PackageName</a>). - </dd> - - <dt><strong><a name="Style">Style</a></strong></dt> - <dd> Syntax: <code> Style [ AllStatic | InterfaceAndImpl |InterfaceOnly | ImplOnly ] </code> <br/> - - (optional) Defines how the Java API for the parsed C headers is - structured. If AllStatic, one concrete Java class will be generated - containing static methods corresponding to the C entry points. If - InterfaceAndImpl, a public Java interface will be generated into the - <a href="#Package">Package</a> with non-static methods corresponding - to the C functions, and an "implementation" concrete Java class - implementing this interface will be generated into the <a - href="#ImplPackage">ImplPackage</a>. If InterfaceOnly, the - InterfaceAndImpl code generation style will be followed, but only the - interface will be generated. If ImplOnly, the InterfaceAndImpl code - generation style will be followed, but only the concrete implementing - class will be generated. The latter two options are useful when - generating a public API in which certain operations are unimplemented - on certain platforms; platform-specific implementation classes can be - generated which implement or leave unimplemented various parts of the - API. - </dd> - - <dt><strong><a name="TemporaryCVariableAssignment">TemporaryCVariableAssignment</a></strong></dt> - <dd> Syntax: <code>TemporaryCVariableAssignment [C function name][code...]</code> <br/> - - (optional) Inserts a C variable assignment declared using the <a - href="#TemporaryCVariableDeclaration">TemporaryCVariableDeclaration</a> - directive in to the body of a particular autogenerated native - method. The assignment is performed immediately after the call to the - underlying C function completes. This is typically used in - conjunction with the <a - href="#ReturnValueCapacity">ReturnValueCapacity</a> or <a - href="#ReturnValueLength">ReturnValueLength</a> directives to capture - the size of a returned C buffer or array of pointers. See the <a - href="#Chapter3">examples</a> for a concrete example of usage of this - directive. Note that unlike, for example, the <a - href="#ReturnedArrayLength">ReturnedArrayLength</a> directive, no - substitution is performed on the supplied code, so the user must - typically have previously looked at the generated code and seen what - work needed to be done and variables needed to be examined at exactly - that line. - </dd> - - <dt><strong><a name="TemporaryCVariableDeclaration">TemporaryCVariableDeclaration</a></strong></dt> - <dd> Syntax: <code>TemporaryCVariableDeclaration [C function name] - [code...]</code> <br/> - - (optional) Inserts a C variable declaration in to the body of a - particular autogenerated native method. This is typically used in - conjunction with the <a - href="#TemporaryCVariableAssignment">TemporaryCVariableAssignment</a> - and <a href="#ReturnValueCapacity">ReturnValueCapacity</a> or <a - href="#ReturnValueLength">ReturnValueLength</a> directives to capture - the size of a returned C buffer or array of pointers. See the <a - href="#Chapter3">examples</a> for a concrete example of usage of this - directive. - </dd> - - <dt><strong><a name="Unignore">Unignore</a></strong></dt> - <dd> Syntax: <code>Unignore [regexp]</code> <br/> - - (optional) Removes a previously-defined <a href="#Ignore">Ignore</a> - directive. This is useful when one configuration file includes - another and wishes to disable some of the Ignores previously - specified. - </dd> - - <dt><strong><a name="Unimplemented">Unimplemented</a></strong></dt> - <dd> Syntax: <code>Unimplemented [regexp]</code> <br/> - - (optional) Causes the binding for the functions matching the passed - regexp to have bodies generated which throw the stated <a - href="#RuntimeExceptionType">RuntimeExceptionType</a> indicating that - this function is unimplemented. This is most useful when an API - contains certain functions that are not supported on all platforms and - there are multiple implementing classes being generated, one per - platform. - </dd> - - </dl> - - <h4><a name="SecProcAddressEmitter">ProcAddressEmitter Configuration</a></h4> - - <p> - - The ProcAddressEmitter is a subclass of the core JavaEmitter which - knows how to call C functions through function pointers. In - particular, the ProcAddressEmitter detects certain constructs in C - header files which imply that the APIs are intended to be called - through function pointers, and generates the glue code appropriately - to support that. - - </p> - <p> - - The ProcAddressEmitter detects pairs of functions and function pointer - typedefs in a set of header files. If it finds a matching pair, it - converts the glue code emission style for that API to look for the - function to call in an autogenerated table called a ProcAddressTable - rather than linking the autogenerated JNI code directly to the - function. It then changes the calling convention of the underlying - native method to pass the function pointer from Java down to C, where - the call-through-function-pointer is performed. - - </p> - <p> - - The ProcAddressEmitter discovers the function and function pointer - pairs by being informed of the mapping between their names by the - user. In the OpenGL and OpenAL libraries, there are fairly simple - mappings between the functions and function pointers. For example, in - the OpenGL <code>glext.h</code> header file, one may find the - following pair: - </p> - <pre> - GLAPI void APIENTRY glFogCoordf (GLfloat); + typedef HANDLE HWND;</code></pre> +<p>Note that it is essential that the type being specified to GlueGen is +compatible at least in semantics with the real definition of the HANDLE +typedef in the real <code>windows.h</code>, so that during compilation +of GlueGen's autogenerated C code, when the real <code>windows.h</code> +is referenced by the C compiler, the autogenerated code will compile +correctly.</p> +<p>This example is not really complete as it also requires <a +href="#Sec32">consideration of the size of data types on 32- and 64-bit +platforms</a> as well as a discussion of how certain <a +href="#SecOpaque">opaque data types</a> are described to GlueGen and +exposed in its autogenerated APIs. Nonetheless, it illustrates at a +basic level why using a stub header is necessary and useful in certain +situations.</p> +<h3 id="32--and-64-bit-considerations"><span id="Sec32">32- and 64-bit +Considerations</span></h3> +<p>When binding C functions to the Java programming language, it is +important that the resulting Java code support execution on a 64-bit +platform if the associated native methods are compiled appropriately. In +other words, the public Java API should not change if the underlying C +data types change to another data model such as LP64 (in which longs and +pointers become 64-bit).</p> +<p>GlueGen internally maintains two descriptions of the underlying C +data model: one for 32-bit architectures and one for 64-bit +architectures. These machine descriptions are used when deciding the +mapping between integral C types such as int and long and the +corresponding Java types, as well as when laying out C structs for +access by the Java language. For each autogenerated C struct accessor, +both a 32-bit and 64-bit variant are generated behind the scenes, +ensuring that the resulting Java code will run correctly on both 32-bit +and 64-bit architectures.</p> +<p>When generating the main class containing the bulk of the method +bindings, GlueGen uses the 64-bit machine description to map C data +types to Java data types. This ensures that the resulting code will run +properly on 64-bit platforms. Note that it also generally means that C +<code>long</code>s will be mapped to Java <code>long</code>s, since an +LP64 data model is assumed.</p> +<p>If <a href="#SecOpaque">Opaque directives</a> are used to cause a +given C integer or pointer data type to be mapped directly to a Java +primitive type, care should be taken to make sure that the Java +primitive type is wide enough to hold all of the data even on 64-bit +platforms. Even if the data type is defined in the header file as being +only a 32-bit C integer, if there is a chance that on a 64-bit platform +the same header may define the data type as a 64-bit C integer or long, +the Opaque directive should map the C type to a Java long.</p> +<h3 id="opaque-directives"><span id="SecOpaque">Opaque +Directives</span></h3> +<p>Complex header files may contain declarations for certain data types +that are either too complex for GlueGen to handle or unnecessarily +complex from the standpoint of glue code generation. In these situations +a stub header may be used to declare a suitably compatible typedef for +the data type. An <a href="#Opaque">Opaque</a> directive can be used to +map the resulting typedef to a Java primitive type if it is undesirable +to expose it as a full-blown Java wrapper class.</p> +<p>GlueGen hashes all typedefs internally down to their underlying +primitive type. (This is probably not really correct according to the C +type system, but is correct enough from a glue code generation +standpoint, where if the types are compatible they are considered +equivalent.) This means that if the parser encounters</p> +<pre><code> typedef void* LPVOID;</code></pre> +<p>then an Opaque directive stating</p> +<pre><code> Opaque long LPVOID</code></pre> +<p>will cause all <code>void*</code> or <code>LPVOID</code> arguments in +the API to be mapped to Java longs, which is almost never desirable. +Unfortunately, it is not currently possible to distinguish between the +LPVOID typedef and the underlying <code>void*</code> data type in this +situation.</p> +<p>A similar problem occurs for other data types for which Opaque +directives may be desired. For example, a Windows HANDLE equates to a +typedef to <code>void*</code>, but performing this typedef in a stub +header and then adding the Opaque directive</p> +<pre><code> Opaque long HANDLE</code></pre> +<p>will cause all void* arguments to be exposed as Java longs instead of +Buffers, which is again undesirable. Attempting to work around the +problem by typedef'ing HANDLE to an integral type, as in:</p> +<pre><code> typedef long HANDLE;</code></pre> +<p>may itself have problems, because GlueGen will assume the two +integral types are compatible and not perform any intermediate casts +between HANDLE and jlong in the autogenerated C code. (When casting +between a pointer type and a JNI integral type such as jlong in C code, +GlueGen automatically inserts casts to convert the pointer first to an +"intptr_t" and then to the appropriate JNI type, in order to silence +compiler warnings and/or errors.)</p> +<p>What is desired is to produce a new type name distinct from all +others but still compatible with the pointer semantics of the original +type. Then an Opaque directive can be used to map the new type name to, +for example, a Java long.</p> +<p>To implement this in the context of the HANDLE example, the following +typedef may be inserted into the stub header:</p> +<pre><code> typedef struct _handle* HANDLE;</code></pre> +<p>This uses a pointer to an anonymous struct name to produce a new +pointer type. This is legal ANSI C and is supported by GlueGen's parser +without having seen a declaration for "struct _handle". Subsequently, an +Opaque directive can be used to map the HANDLE data type to a Java +long:</p> +<pre><code> Opaque long HANDLE</code></pre> +<p>Now HANDLEs are exposed to Java as longs as desired. A similar +technique is used to expose XIDs on the X11 platform as Java longs.</p> +<h3 id="argument-name-substitution"><span id="SecSubstitution">Argument +Name Substitution</span></h3> +<p>Certain configuration file directives allow the insertion of Java or +C code at various places in the generated glue code, to both eliminate +the need to hand-edit the generated glue code as well as to minimize the +hand-writing of glue code, which sidesteps the GlueGen process. In some +situations the inserted code may reference incoming arguments to compute +some value or perform some operation. Examples of directives supporting +this substitution include <a +href="#ReturnValueCapacity">ReturnValueCapacity</a> and <a +href="#ReturnedArrayLength">ReturnedArrayLength</a>.</p> +<p>The expressions in these directives may contain Java MessageFormat +expressions like <code>{0}</code> which refer to the incoming argument +names to the function. <code>{0}</code> refers to the first incoming +argument.</p> +<p>Strongly-typed C primitive pointers such as <code>int*</code>, which +ordinarily expand to overloaded Java methods taking e.g. +<code>int[]</code> as well as <code>IntBuffer</code>, present a problem. +The expansion to <code>int[] arr</code> also generates an +<code>int arr_offset</code> argument to be able to pass a pointer into +the middle of the array down to C. To allow the same MessageFormat +expression to be used for both cases, the subsitution that occurs when +such a primitive array is referenced is the string +<code>arr, arr_offset</code>; in other +words, the subtituted string contains a comma. This construct may be +used in the following way: the code being manually inserted may itself +contain a method call taking e.g. <code>{3}</code> (the incoming +argument index of the primitive array or buffer). The user should supply +two overloaded versions of this method, one taking a strongly-typed +Buffer and one taking e.g. an <code>int[] arr</code> and +<code>int arr_offset</code> argument. The implementation of +<code>RangeCheck</code>s for primitive arrays and strongly-typed buffers +uses this construct.</p> +<p>It should be noted that in the autogenerated C code the offset +argument is expressed in bytes while at the Java level it is expressed +in elements. Most uses of GlueGen will probably not have to refer to the +primitive array arguments in C code so this slight confusion should be +minor.</p> +<h3 +id="configuration-file-directives"><span id="SecConfiguration">Configuration +File Directives</span></h3> +<p>In addition to the C headers, GlueGen requires a certain amount of +metadata in the form of configuration files in order to produce its glue +code. There are three basic reasons for this: first, GlueGen must be +informed into which Java classes the C methods are to be bound; second, +there are many configuration options for the generated glue code, and +passing them all on the command line is infeasible; and third, there are +ambiguities in many constructs in the C programming language which must +be resolved before a Java binding can be produced.</p> +<p>The contents of the configuration file are dependent on the class of +emitter specified to GlueGen. Currently there are three built-in emitter +classes: JavaEmitter, which produces a basic, static Java binding of C +functions; ProcAddressEmitter, which extends JavaEmitter by calling the +underlying C functions through function pointers, resulting in more +dynamic behavior and supporting C APIs with optional functionality; and +GLEmitter, which specializes ProcAddressEmitter to support some +OpenGL-specific constructs. The GLEmitter will be ignored in this manual +as it is specialized for JOGL and provides very little additional +functionality beyond the ProcAddressEmitter. The JavaEmitter and +ProcAddressEmitter support many options in their configuration files. As +the ProcAddressEmitter is a subclass of JavaEmitter, all of the +constructs in the JavaEmitter's configuration files are also legal in +the ProcAddressEmitter's configuration files.</p> +<p>The configuration files have a very simple line-by-line structure, +and are parsed by a very rudimentary, hand-written parser. Each +non-whitespace and non-comment line (note: comment lines begin with '#') +contains a directive like <code>Package</code>, <code>Style</code> or +<code>JavaClass</code> followed by arguments to that directive. There +are a certain set of directives that are required for any code +generation; others are optional and their omission results in some +default behavior. Directives are case-insensitive.</p> +<p>The following is an exhaustive list of the options currently +supported by each of these emitters' configuration files. It is +difficult to see exactly how to use the tool based simply on these +descriptions, so the <a href="#Chapter3">examples</a> may be more +helpful in seeing exactly how to structure a configuration file for +proper glue code generation.</p> +<h4 id="javaemitter-configuration"><span id="SecJavaEmitter">JavaEmitter +Configuration</span></h4> +<p>Note that only a very few of the following directives are specified +as being "required" rather than "optional"; these indicate the minimal +directives needed for a valid configuration file to begin to get glue +code to be produced. In general, these are <a +href="#Package">Package</a>, <a href="#ImplPackage">ImplPackage</a>, <a +href="#JavaClass">JavaClass</a>, <a +href="#ImplJavaClass">ImplJavaClass</a>, and <a href="#Style">Style</a>. +Other directives such as <a href="#NioDirectOnly">NioDirectOnly</a> are +required in some circumstances for the glue code to be correct, and some +such as <a href="#ReturnedArrayLength">ReturnedArrayLength</a>, <a +href="#ReturnValueCapacity">ReturnValueCapacity</a>, and <a +href="#ReturnValueLength">ReturnValueLength</a> should be specified in +some situations in order for certain return values to be useful at the +Java level.</p> +<p>The following directives are specified in alphabetical order, +although this is not necessarily the best semantic order.</p> +<p><strong><span id="AccessControl">AccessControl</span></strong><br /> +Syntax: +<code>AccessControl [method name] [ PUBLIC | PROTECTED | PRIVATE | PACKAGE_PRIVATE ]</code><br /> +(optional) Controls the access control of a certain Java method +corresponding to a C function. The access control of all APIs defaults +to public. This is useful when using the C binding of a particular +function only as one implementation strategy of the real public API and +using <a href="#CustomJavaCode">CustomJavaCode</a> to write the exposed +API. In this case is most useful in conjunction with <a +href="#RenameJavaMethod">RenameJavaMethod</a>.</p> +<p><strong><span id="ArgumentIsString">ArgumentIsString</span></strong><br /> +Syntax: +<code>ArgumentIsString [function name] [indices...]</code> +where the first argument index is 0<br /> +(optional) For a C function with one or more outgoing <code>char*</code> +(or compatible data type) arguments, indicates that those arguments are +semantically null-terminated C strings rather than arbitrary arrays of +bytes. The generated glue code will be modified to emit those arguments +as java.lang.String objects rather than <code>byte[]</code> or +<code>ByteBuffer</code>.</p> +<p><strong><span id="ArgumentIsPascalString">ArgumentIsPascalString</span></strong><br /> +Syntax: +<code>ArgumentIsPascalString [function name] [indice-tuples...]</code>, +with each tuple being the argument-index for the +'<code>int length</code>' and the '<code>char* value</code>' argument +with index 0 for the the first argument<br /> +(optional) For a C function with one or more outgoing +'<code>int length</code>' and '<code>char* value</code>' (or compatible +data type) arguments, indicates that those arguments are semantically +non-null-terminated Pascal strings rather than null-terminated C strings +or arbitrary arrays of bytes. The generated glue code will be modified +to emit those arguments as java.lang.String objects rather than +<code>byte[]</code> or <code>ByteBuffer</code>.</p> +<p><strong><span id="ClassJavadoc">ClassJavadoc</span></strong><br /> +Syntax: <code>ClassJavadoc [class name] [code...]</code><br /> +(optional) Causes the specified line of code to be emitted in the +appropriate place in the generated code to become the per-class Javadoc +for the specified class. By default GlueGen produces no Javadoc for its +generated classes, so this is the mechanism by which a user can emit +Javadoc for these classes. The specified Javadoc undergoes no +transformation by GlueGen, so the initial <code>/**</code> and trailing +<code>*/</code> must be included in the correct place. Each line of +Javadoc is emitted in the order encountered during parsing of the +configuration files.</p> +<p><strong><span id="CustomCCode">CustomCCode</span></strong><br /> +Syntax: <code>CustomCCode [code...]</code><br /> +(optional) Causes the specified line of C code to be emitted into the +generated native code for the implementing class. Currently there is no +way (and no real need) to be able to emit custom C code into any other +generated .c file, so the class name in the <a +href="#CustomJavaCode">CustomJavaCode</a> directive is omitted.</p> +<p><strong><span id="CustomJavaCode">CustomJavaCode</span></strong><br /> +Syntax: <code>CustomJavaCode [class name] [code...]</code><br /> +(optional) Causes the specified line of Java code to be emitted into the +specified generated Java class. Can be used to emit code into any +generated class: the public interface, the implementing class, the sole +concrete class (in the case of the AllStatic <a +href="#Style">Style</a>), or any of the Java classes corresponding to +referenced C structs in the parsed headers. This usage is somewhat +verbose, and the <a href="#IncludeAs">IncludeAs</a> directive provides a +more concise way of including large bodies of Java code into the +generated code.</p> +<p><strong><span id="CustomJNICode">CustomJNICode</span></strong><br /> +Syntax: <code>CustomJNICode [class name] [code...]</code><br /> +(optional) Causes the specified line of C code to be emitted into the +generated JNI code related of specified Java class. Can be used to emit +JNI code related of any generated class: the public interface, the +implementing class, the sole concrete class (in the case of the +AllStatic <a href="#Style">Style</a>), or any of the Java classes +corresponding to referenced C structs in the parsed headers. This usage +is somewhat verbose, and the <a href="#IncludeAs">IncludeAs</a> +directive provides a more concise way of including large bodies of C +code into the generated code.</p> +<p><strong><span id="EmitStruct">EmitStruct</span></strong><br /> +Syntax: <code>EmitStruct [C struct type name]</code><br /> +(optional) Forces a Java class to be emitted for the specified C struct. +Normally only those structs referenced directly by the parsed C APIs +have corresponding Java classes emitted.</p> +<p><strong><span id="GlueGenRuntimePackage">GlueGenRuntimePackage</span></strong><br /> +Syntax: +<code>GlueGenRuntimePackage [package name, like com.jogamp.gluegen.runtime]</code><br /> +(optional) Changes the package in which the generated glue code expects +to find its run-time helper classes (like Buffers, CPU, StructAccessor). +Defaults to <code>com.jogamp.gluegen.runtime</code> (no quotes). This is +useful if you want to bundle the runtime classes in your application +without the possibility of interfering with other versions elsewhere in +the system.</p> +<p><strong><span id="ExtendedInterfaceSymbolsIgnore">ExtendedInterfaceSymbolsIgnore</span></strong><br /> +Syntax: <code>ExtendedInterfaceSymbolsIgnore [Java file]</code><br /> +(optional) Causes all autogenerated Java interface ignore all symbols +from interface declared inside named Java source file.<br /> +This directive can be used with <a href="#Extends">Extends</a> +directive.<br /> +Cf here for more information : <a +href="../GlueGen_Mapping.html#oo-style-example">GlueGen_Mapping</a></p> +<p><strong><span id="ExtendedInterfaceSymbolsOnly">ExtendedInterfaceSymbolsOnly</span></strong><br /> +Syntax: <code>ExtendedInterfaceSymbolsOnly [Java file]</code><br /> +(optional) Causes all autogenerated Java interface generate only symbols +from interface declared inside named Java source file.<br /> +This directive can be used with <a href="#Extends">Extends</a> +directive.<br /> +Cf here for more information : <a +href="../GlueGen_Mapping.html#oo-style-example">GlueGen_Mapping</a></p> +<p><strong><span id="ExtendedImplementationSymbolsIgnore">ExtendedImplementationSymbolsIgnore</span></strong><br /> +Syntax: +<code>ExtendedImplementationSymbolsIgnore [Java file]</code><br /> +(optional) Causes all autogenerated Java classes ignore all symbols from +interface or classe declared inside named Java source file.<br /> +This directive can be used with <a href="#ParentClass">ParentClass</a> +directive.<br /> +Cf here for more information : <a +href="../GlueGen_Mapping.html#oo-style-example">GlueGen_Mapping</a></p> +<p><strong><span id="ExtendedImplementationSymbolsOnly">ExtendedImplementationSymbolsOnly</span></strong><br /> +Syntax: <code>ExtendedImplementationSymbolsOnly [Java file]</code><br /> +(optional) Causes all autogenerated Java classes generate only symbols +from interface or classe declared inside named Java source file.<br /> +This directive can be used with <a href="#ParentClass">ParentClass</a> +directive.<br /> +Cf here for more information : <a +href="../GlueGen_Mapping.html#oo-style-example">GlueGen_Mapping</a></p> +<p><strong><span id="ExtendedIntfAndImplSymbolsIgnore">ExtendedIntfAndImplSymbolsIgnore</span></strong><br /> +Syntax: <code>ExtendedIntfAndImplSymbolsIgnore [Java file]</code><br /> +(optional) Causes all autogenerated Java interface and classes ignore +all symbols from interface or classe declared inside named Java source +file.<br /> +This directive can be used with <a href="#Extends">Extends</a> or <a +href="#ParentClass">ParentClass</a> directives.<br /> +Cf here for more information : <a +href="../GlueGen_Mapping.html#oo-style-example">GlueGen_Mapping</a></p> +<p><strong><span id="ExtendedIntfAndImplSymbolsOnly">ExtendedIntfAndImplSymbolsOnly</span></strong><br /> +Syntax: <code>ExtendedIntfAndImplSymbolsOnly [Java file]</code><br /> +(optional) Causes all autogenerated Java interface and classes generate +only symbols from interface or classe declared inside named Java source +file.<br /> +This directive can be used with <a href="#Extends">Extends</a> or <a +href="#ParentClass">ParentClass</a> directives.<br /> +Cf here for more information : <a +href="../GlueGen_Mapping.html#oo-style-example">GlueGen_Mapping</a></p> +<p><strong><span id="Extends">Extends</span></strong><br /> +Syntax: +<code>Extends [Java interface name] [interface name to extend] </code><br /> +(optional) Causes the specified autogenerated Java interface to declare +that it extends another one. This directive may only be applied to +autogenerated interfaces, not concrete classes. For concrete classes, +use <a href="#Implements">Implements</a> directive or <a +href="#ParentClass">ParentClass</a> directive.</p> +<p><strong><span id="HierarchicalNativeOutput">HierarchicalNativeOutput</span></strong><br /> +Syntax: <code>HierarchicalNativeOutput true</code><br /> +(optional) If "true", makes subdirectories for the generated native code +matching the package names of the associated classes. This is typically +not needed (or desired, as it complicates the compilation process for +this native code) and defaults to false.</p> +<p><strong><span id="Ignore">Ignore</span></strong><br /> +Syntax: <code>Ignore [regexp]</code><br /> +(optional) Ignores one or more functions or data types matching the +regexp argument which are encountered during parsing of the C headers. +By default GlueGen will emit all encountered C functions as well as Java +classes corresponding to all C structs referenced by those functions. +Related directives are <a href="#IgnoreNot">IgnoreNot</a>, <a +href="#Unignore">Unignore</a> and <a +href="#EmitStruct">EmitStruct</a>.</p> +<p><strong><span id="IgnoreField">IgnoreField</span></strong><br /> +Syntax: <code>IgnoreField [struct type name] [field name]</code><br /> +(optional) Causes the specified field of the specified struct type to be +ignored during code generation, typically because it is too complex for +GlueGen to handle.</p> +<p><strong><span id="IgnoreNot">IgnoreNot</span></strong><br /> +Syntax: see <a href="#Ignore">Ignore</a>. (optional) Similar to the <a +href="#Ignore">Ignore</a> directive, but evaluates the negation of the +passed regexp when deciding whether to ignore the given function or data +type. The <a href="#Unignore">Unignore</a> mechanism may be used with +IgnoreNot as well. NOTE: the IgnoreNot mechanism may ultimately turn out +to be superfluous; the authors do not have sufficient experience with +regular expressions to know whether general negation of a regexp is +possible. Feedback in this area would be appreciated.</p> +<p><strong><span id="Implements">Implements</span></strong><br /> +Syntax: +<code>Implements [Java class name] [interface name to implement]</code><br /> +(optional) Causes the specified autogenerated Java concrete class to +declare that it implements the specified interface. This directive may +only be applied to autogenerated concrete classes, not interfaces. For +interfaces, use the <a href="#Extends">Extends</a> directive.</p> +<p><strong><span id="ImplJavaClass">ImplJavaClass</span></strong><br /> +Syntax: <code>ImplJavaClass [class name]</code><br /> +(optional) Specifies the name of the typically non-public, +implementation Java class which contains the concrete Java and native +methods for the glue code. If the emission style is AllStatic, there is +no distinction between the public and implementation class and +ImplJavaClass should not be specified. Otherwise, if the ImplJavaClass +is unspecified, it defaults to the JavaClass name plus "Impl". (If both +are unspecified in this configuration, an error is reported.) See also +<a href="#JavaClass">JavaClass</a>.</p> +<p><strong><span id="ImplPackage">ImplPackage</span></strong><br /> +Syntax: <code>ImplPackage [package name]</code><br /> +(optional) Specifies the package name into which the implementing class +containing the concrete Java and native methods will be emitted, +assuming an emission style of InterfaceAndImpl or ImplOnly. If +AllStatic, there is no separate implementing class from the public +interface. If the emission style is not AllStatic and the ImplPackage is +not specified, it defaults to the Package plus ".impl". See also <a +href="#Package">Package</a>.</p> +<p><strong><span id="Import">Import</span></strong><br /> +Syntax: <code>Import [package name]</code> (no trailing semicolon)<br /> +(optional) Adds an import statement at the top of each generated Java +source file.</p> +<p><strong><span id="Include">Include</span></strong><br /> +Syntax: <code>Include [filename]</code><br /> +(optional) Causes another configuration file to be read at the current +point in parsing the current configuration file. The filename argument +may be either absolute or relative; in the latter case it is specified +relative to the location of the current configuration file.</p> +<p><strong><span id="IncludeAs">IncludeAs</span></strong><br /> +Syntax: <code>IncludeAs [prefix tokens] [filename]</code><br /> +(optional) Similar to the <a href="#Include">Include</a> directive, but +prepends the specified prefix tokens on to every line of the file to be +read. The last token parsed is the name of the file to be read. This +allows, for example, <a href="#CustomJavaCode">CustomJavaCode</a> to be +stored as Java source rather than in the configuration file; in this +example the configuration file might contain +<code>IncludeAs CustomJavaCode MyClass MyClass-CustomJavaCode.java</code>.</p> +<p><strong><span id="JavaClass">JavaClass</span></strong><br /> +Syntax: <code>JavaClass [class name]</code><br /> +(optional / required) Specifies the name of the public, +non-implementation Java class or interface into which the glue code will +be generated. If the emission style is not ImplOnly, the JavaClass +directive is required. See also <a +href="#ImplJavaClass">ImplJavaClass</a>.</p> +<p><strong><span id="JavaEpilogue">JavaEpilogue</span></strong><br /> +Syntax: <code>JavaEpilogue [C function name] [code...]</code><br /> +(optional) Adds the specified code as an epilogue in the Java method for +the specified C function; this code is run after the underlying C +function has been called via the native method but before any result is +returned. As in the <a +href="#ReturnedArrayLength">ReturnedArrayLength</a> and other +directives, <a href="#SecSubstitution">argument name substitution</a> is +performed on MessageFormat expressions in the specified code. See also +<a href="#JavaPrologue">JavaPrologue</a>.</p> +<p><strong><span id="JavaOutputDir">JavaOutputDir</span></strong><br /> +Syntax: <code>JavaOutputDir [directory name]</code><br /> +(optional) Specifies the root directory into which the emitted Java code +will be produced. Subdirectories for the packages of the associated Java +classes will be automatically created. If unspecified, defaults to the +current working directory.</p> +<p><strong><span id="JavaPrologue">JavaPrologue</span></strong><br /> +Syntax: <code>JavaPrologue [C function name] [code...]</code><br /> +(optional) Adds the specified code as a prologue in the Java method for +the specified C function; this code is run before the underlying C +function is called via the native method. As in the <a +href="#ReturnedArrayLength">ReturnedArrayLength</a> and other +directives, <a href="#SecSubstitution">argument name substitution</a> is +performed on MessageFormat expressions in the specified code. See also +<a href="#JavaEpilogue">JavaEpilogue</a>.</p> +<p><strong><span id="ManuallyImplement">ManuallyImplement</span></strong><br /> +Syntax: <code>ManuallyImplement [function name]</code><br /> +(optional) Indicates to GlueGen to not produce a method into the +implementing class for the specified C function; the user must provide +one via the <a href="#CustomJavaCode">CustomJavaCode</a> directive. If +the emission style is InterfaceAndImpl or InterfaceOnly, a public method +will still be generated for the specified function.</p> +<p><strong><span id="MaxOneElement">MaxOneElement</span></strong><br /> +Syntax: <code>MaxOneElement [function name]</code><br /> +(optional) Indicates that the specified C function/attribute which +returns a single element instead a ByteBuffer if signature or compatible +type actually returns a pointer like int* but isn't an array.<br /> +Cf here for more information : <a +href="../GlueGen_Mapping.html#gluegen-struct-settings">GlueGen_Mapping</a></p> +<p><strong><span id="NativeOutputDir">NativeOutputDir</span></strong><br /> +Syntax: <code>NativeOutputDir [directory name]</code><br /> +(optional) Specifies the root directory into which the emitted JNI code +will be produced. If unspecified, defaults to the current working +directory. See also <a +href="#HierarchicalNativeOutput">HierarchicalNativeOutput</a>.</p> +<p><strong><span id="NioDirectOnly">NioDirectOnly</span></strong><br /> +Syntax: <code>NioDirectOnly [function name]</code><br /> +(required when necessary) When passing a pointer down to a C API, it is +semantically undefined whether the underlying C code expects to treat +that pointer as a persistent pointer, living past the point of return of +the function call, or whether the pointer is used only during the +duration of the function call. For APIs taking C primitive pointers such +as <code>void*</code>, <code>float*</code>, etc., GlueGen will typically +generate up to two overloaded Java methods, one taking a +<code>Buffer</code> or <code>Buffer</code> subclass such as +<code>FloatBuffer</code>, and one taking a primitive array such as +<code>float[]</code>. (In the case of <code>void*</code> outgoing +arguments, GlueGen produces only one variant taking a Buffer.) Normally +the generated glue code accepts either a "direct" or non-"direct" buffer +(according to the New I/O APIs) as argument. However, if the semantics +of the C function are that it either expects to hold on to this pointer +past the point of the function call, or if it can block while holding on +to the pointer, the <code>NioDirectOnly</code> directive +<strong>must</strong> be specified for this C function in order for the +generated glue code to be correct. Failing to observe this requirement +may cause JVM hangs or crashes.</p> +<p><strong><span id="Opaque">Opaque</span></strong><br /> +Syntax: +<code>Opaque [Java primitive data type] [C data type]</code><br /> +(optional) Causes a particular C data type to be exposed in opaque form +as a Java primitive type. This is most useful for certain pointer types +for which it is not desired to generate full Java classes but instead +expose them to Java as e.g. <code>long</code>s. It is also useful for +forcing certain integral C data types to be exposed as e.g. +<code>long</code> to Java to ensure 64-bit cleanliness of the generated +glue code. See the <a href="#Chapter3">examples</a>. The C data type may +be a multiple-level pointer type; for example +<code>Opaque long void**</code>. Note that it is not currently supported +to make a given data type opaque for just a few functions; the Opaque +directive currently applies to all C functions in the headers being +parsed. This means that sweeping Opaque declarations like +<code>Opaque long void*</code> will likely have unforseen and +undesirable consequences.</p> +<p><strong><span id="Package">Package</span></strong><br /> +Syntax: <code>Package [package name]</code> (no trailing +semicolon)<br /> +(optional / required) Specifies the package into which the public +interface or class for the autogenerated glue code will be generated. +Required whenever the emission style is not ImplOnly. See also <a +href="#ImplPackage">ImplPackage</a>.</p> +<p><strong><span id="ParentClass">ParentClass</span></strong><br /> +Syntax: +<code>ParentClass [Java class name] [class name to extend] </code><br /> +(optional) Causes the specified autogenerated Java classe to declare +that it extends another one. This directive may only be applied to +autogenerated classes, not interface. For interfaces, use the <a +href="#Extends">Extends</a> directive.</p> +<p><strong><span id="RangeCheck">RangeCheck</span></strong><br /> +Syntax: +<code>RangeCheck [C function name] [argument number] [expression]</code><br /> +(optional) Causes a range check to be performed on the specified array +or Buffer argument of the specified autogenerated Java method. This +range check ensures, for example, that a certain number of elements are +remaining in the passed Buffer, knowing that the underlying C API will +access no more than that number of elements. For range checks that +should be expressed in terms of a number of bytes rather than a number +of elements, see the <a href="#RangeCheckBytes">RangeCheckBytes</a> +directive. As in the <a +href="#ReturnedArrayLength">ReturnedArrayLength</a> and other +directives, <a href="#SecSubstitution">argument name substitution</a> is +performed on MessageFormat expressions.</p> +<p><strong><span id="RangeCheckBytes">RangeCheckBytes</span></strong><br /> +Syntax: +<code>RangeCheckBytes [C function name] [argument number] [expression]</code><br /> +(optional) Same as the <a href="#RangeCheck">RangeCheck</a> directive, +but the specified expression is treated as a minimum number of bytes +remaining rather than a minimum number of elements remaining. This +directive may not be used with primitive arrays.</p> +<p><strong><span id="RenameJavaMethod">RenameJavaMethod</span></strong><br /> +Syntax: <code>RenameJavaMethod [from name] [to name]</code><br /> +(optional) Causes the specified C function to be emitted under a +different name in the Java binding. This is most useful in conjunction +with the <a href="#AccessControl">AccessControl</a> directive when the C +function being bound to Java is only one potential implementation of the +public API, or when a considerable amount of Java-side custom code is +desired to wrap the underlying C native method entry point.</p> +<p><strong><span id="RenameJavaType">RenameJavaType</span></strong><br /> +Syntax: <code>RenameJavaType [from name] [to name]</code><br /> +(optional) Causes the specified C struct to be exposed as a Java class +under a different name. This only applies to autogenerated classes +corresponding to C structs encountered during glue code generation; full +control is provided over the name of the top-level classes associated +with the set of C functions via the <a href="#JavaClass">JavaClass</a> +and <a href="#ImplJavaClass">ImplJavaClass</a> directives.</p> +<p><strong><span id="ReturnedArrayLength">ReturnedArrayLength</span></strong><br /> +Syntax: +<code>ReturnedArrayLength [C function name] [expression]</code> +where <code>expression</code> is a legal Java expression with +MessageFormat specifiers such as "{0}". These specifiers will be +replaced in the generated glue code with the incoming argument names +where the first argument to the method is numbered 0. See the section on +<a href="#SecSubstitution">argument name substitution</a>.<br /> +(optional) For a function returning a compound C pointer type such as an +<code>XVisualInfo*</code>, indicates that the returned pointer is to be +treated as an array and specifies the length of the returned array as a +function of the arguments passed to the function. Note that this +directive differs subtly from <a +href="#ReturnValueCapacity">ReturnValueCapacity</a> and +ReturnValueLength. It is also sometimes most useful in conjunction with +the <a +href="#TemporaryCVariableDeclaration">TemporaryCVariableDeclaration</a> +and TemporaryCVariableAssignment directives.</p> +<p><strong><span id="ReturnsString">ReturnsString</span></strong><br /> +Syntax: <code>ReturnsString [function name]</code><br /> +(optional) Indicates that the specified C function which returns a +<code>char*</code> or compatible type actually returns a null-terminated +C string which should be exposed as a java.lang.String. NOTE: currently +does not properly handle the case where this storage needs to be freed +by the end user. In these situations the data should be returned as a +direct ByteBuffer, the ByteBuffer converted to a String using custom +Java code, and the ByteBuffer freed manually using another function +bound to Java.</p> +<p><strong><span id="ReturnsStringOnly">ReturnsStringOnly</span></strong><br /> +Syntax: <code>ReturnsStringOnly [function name]</code><br /> +(optional) Like the <a href="#ReturnsString">ReturnsString</a> +instruction, but without the classic getters and setters with +ByteBuffer.<br /> +Cf here for more information : <a +href="../GlueGen_Mapping.html#gluegen-struct-settings">GlueGen_Mapping</a></p> +<p><strong><span id="ReturnValueCapacity">ReturnValueCapacity</span></strong><br /> +Syntax: +<code>ReturnValueCapacity [C function name] [expression]</code><br /> +(optional) Specifies the capacity of a java.nio <code>Buffer</code> or +subclass wrapping a C primitive pointer such as <code>char*</code> or +<code>float*</code> being returned from a C function. Typically +necessary in order to properly use such pointer return results from +Java. As in the <a href="#ReturnedArrayLength">ReturnedArrayLength</a> +directive, <a href="#SecSubstitution">argument name substitution</a> is +performed on MessageFormat expressions.</p> +<p><strong><span id="ReturnValueLength">ReturnValueLength</span></strong><br /> +Syntax: +<code>ReturnValueLength [C function name] [expression]</code><br /> +(optional) Specifies the length of a returned array of pointers, +typically to C structs, from a C function. This differs from the <a +href="#ReturnedArrayLength">ReturnedArrayLength</a> directive in the +pointer indirection to the array elements. The <a +href="#ReturnedArrayLength">ReturnedArrayLength</a> directive handles +slicing up of a linear array of structs, while the ReturnValueLength +directive handles boxing of individual elements of the array (which are +pointers) in to the Java class which wraps that C struct type. See the +<a href="#Chapter3">examples</a> for a concrete example of usage. As in +the <a href="#ReturnedArrayLength">ReturnedArrayLength</a> directive, <a +href="#SecSubstitution">argument name substitution</a> is performed on +MessageFormat expressions.</p> +<p><strong><span id="RuntimeExceptionType">RuntimeExceptionType</span></strong><br /> +Syntax: <code>RuntimeExceptionType [class name]</code><br /> +(optional) Specifies the class name of the exception type which should +be thrown when run-time related exceptions occur in the generated glue +code, for example if a non-direct Buffer is passed to a method for which +<a href="#NioDirectOnly">NioDirectOnly</a> was specified. Defaults to +<code>RuntimeException</code>.</p> +<p><strong><span id="StructPackage">StructPackage</span></strong><br /> +Syntax: +<code>StructPackage [C struct type name] [package name]</code>. +Package name contains no trailing semicolon.<br /> +(optional) Indicates that the specified Java class corresponding to the +specified C struct should be placed in the specified package. By +default, these autogenerated Java classes corresponding to C structs are +placed in the main package (that defined by <a +href="#PackageName">PackageName</a>).</p> +<p><strong><span id="Style">Style</span></strong><br /> +Syntax: +<code>Style [ AllStatic | InterfaceAndImpl |InterfaceOnly | ImplOnly ]</code><br /> +(optional) Defines how the Java API for the parsed C headers is +structured. If AllStatic, one concrete Java class will be generated +containing static methods corresponding to the C entry points. If +InterfaceAndImpl, a public Java interface will be generated into the <a +href="#Package">Package</a> with non-static methods corresponding to the +C functions, and an "implementation" concrete Java class implementing +this interface will be generated into the <a +href="#ImplPackage">ImplPackage</a>. If InterfaceOnly, the +InterfaceAndImpl code generation style will be followed, but only the +interface will be generated. If ImplOnly, the InterfaceAndImpl code +generation style will be followed, but only the concrete implementing +class will be generated. The latter two options are useful when +generating a public API in which certain operations are unimplemented on +certain platforms; platform-specific implementation classes can be +generated which implement or leave unimplemented various parts of the +API.</p> +<p><strong><span id="TemporaryCVariableAssignment">TemporaryCVariableAssignment</span></strong><br /> +Syntax: +<code>TemporaryCVariableAssignment [C function name][code...]</code><br /> +(optional) Inserts a C variable assignment declared using the <a +href="#TemporaryCVariableDeclaration">TemporaryCVariableDeclaration</a> +directive in to the body of a particular autogenerated native method. +The assignment is performed immediately after the call to the underlying +C function completes. This is typically used in conjunction with the <a +href="#ReturnValueCapacity">ReturnValueCapacity</a> or <a +href="#ReturnValueLength">ReturnValueLength</a> directives to capture +the size of a returned C buffer or array of pointers. See the <a +href="#Chapter3">examples</a> for a concrete example of usage of this +directive. Note that unlike, for example, the <a +href="#ReturnedArrayLength">ReturnedArrayLength</a> directive, no +substitution is performed on the supplied code, so the user must +typically have previously looked at the generated code and seen what +work needed to be done and variables needed to be examined at exactly +that line.</p> +<p><strong><span id="TemporaryCVariableDeclaration">TemporaryCVariableDeclaration</span></strong><br /> +Syntax: +<code>TemporaryCVariableDeclaration [C function name] [code...]</code><br /> +(optional) Inserts a C variable declaration in to the body of a +particular autogenerated native method. This is typically used in +conjunction with the <a +href="#TemporaryCVariableAssignment">TemporaryCVariableAssignment</a> +and <a href="#ReturnValueCapacity">ReturnValueCapacity</a> or <a +href="#ReturnValueLength">ReturnValueLength</a> directives to capture +the size of a returned C buffer or array of pointers. See the <a +href="#Chapter3">examples</a> for a concrete example of usage of this +directive.</p> +<p><strong><span id="Unignore">Unignore</span></strong><br /> +Syntax: <code>Unignore [regexp]</code><br /> +(optional) Removes a previously-defined <a href="#Ignore">Ignore</a> +directive. This is useful when one configuration file includes another +and wishes to disable some of the Ignores previously specified.</p> +<p><strong><span id="Unimplemented">Unimplemented</span></strong><br /> +Syntax: <code>Unimplemented [regexp]</code><br /> +(optional) Causes the binding for the functions matching the passed +regexp to have bodies generated which throw the stated <a +href="#RuntimeExceptionType">RuntimeExceptionType</a> indicating that +this function is unimplemented. This is most useful when an API contains +certain functions that are not supported on all platforms and there are +multiple implementing classes being generated, one per platform.</p> +<h4 +id="procaddressemitter-configuration"><span id="SecProcAddressEmitter">ProcAddressEmitter +Configuration</span></h4> +<p>The ProcAddressEmitter is a subclass of the core JavaEmitter which +knows how to call C functions through function pointers. In particular, +the ProcAddressEmitter detects certain constructs in C header files +which imply that the APIs are intended to be called through function +pointers, and generates the glue code appropriately to support that.</p> +<p>The ProcAddressEmitter detects pairs of functions and function +pointer typedefs in a set of header files. If it finds a matching pair, +it converts the glue code emission style for that API to look for the +function to call in an autogenerated table called a ProcAddressTable +rather than linking the autogenerated JNI code directly to the function. +It then changes the calling convention of the underlying native method +to pass the function pointer from Java down to C, where the +call-through-function-pointer is performed.</p> +<p>The ProcAddressEmitter discovers the function and function pointer +pairs by being informed of the mapping between their names by the user. +In the OpenGL and OpenAL libraries, there are fairly simple mappings +between the functions and function pointers. For example, in the OpenGL +<code>glext.h</code> header file, one may find the following pair:</p> +<pre><code> GLAPI void APIENTRY glFogCoordf (GLfloat); ... - typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord); - </pre> - <p> - Therefore the mapping rule between the function name and the function - pointer typedef for the OpenGL extension header file is "PFN + - Uppercase(funcname) + PROC". Similarly, in the OpenAL 1.1 header - files, one may find the following pair: - </p> - <pre> - AL_API void AL_APIENTRY alEnable( ALenum capability ); + typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord);</code></pre> +<p>Therefore the mapping rule between the function name and the function +pointer typedef for the OpenGL extension header file is "PFN + +Uppercase(funcname) + PROC". Similarly, in the OpenAL 1.1 header files, +one may find the following pair:</p> +<pre><code> AL_API void AL_APIENTRY alEnable( ALenum capability ); ... - typedef void (AL_APIENTRY *LPALENABLE)( ALenum capability ); - </pre> - <p> - Therefore the mapping rule between the function name and the function - pointer typedef for the OpenAL header files is "LP + - Uppercase(funcname)". - - </p> - <p> - - These are the two principal function pointer-based APIs toward which - the GlueGen tool has currently been applied. It may turn out to be - that this simple mapping heuristic is insufficient, in which case it - will need to be extended in a future version of the GlueGen tool. - - </p> - <p> - - Note that it is currently the case that in order for the - ProcAddressEmitter to notice that a given function should be called - through a function pointer, it must see both the function prototype as - well as the function pointer typedef. Some headers, in particular the - OpenAL headers, have their <code>#ifdefs</code> structured in such a - way that either the declaration or the typedef is visible, but not - both simultaneously. Because the <a href="#SecJCPP">JCPP</a> C - preprocessor GlueGen uses obeys <code>#ifdefs</code>, it is in a - situation like this that the headers would have to be modified to - allow GlueGen to see both declarations. - - </p> - <p> - - The following directives are specified in alphabetical order, although - this is not necessarily the best semantic order. The - ProcAddressEmitter also accepts all of the directives supported by the - JavaEmitter. The required directives are <a - href="#GetProcAddressTableExpr">GetProcAddressTableExpr</a> and <a - href="#ProcAddressNameExpr">ProcAddressNameExpr</a>. - - </p> - - <dl> - - <dt><strong><a name="EmitProcAddressTable">EmitProcAddressTable</a></strong></dt> - <dd> Syntax: <code>EmitProcAddressTable [true | false]</code> <br/> - - (optional) Indicates whether to emit the ProcAddressTable during glue - code generation. Defaults to false. - </dd> - - <dt><strong><a name="ForceProcAddressGen">ForceProcAddressGen</a></strong></dt> - <dd> Syntax: <code>ForceProcAddressGen [function name]</code> <br/> - - (optional) Indicates that a ProcAddressTable entry should be produced - for the specified function even though it does not have an associated - function pointer typedef in the header. This directive does not - currently cause the autogenerated Java and C code to change to - call-through-function-pointer style, which should probably be - considered a bug. (FIXME) - </dd> - - <dt><strong><a name="GetProcAddressTableExpr">GetProcAddressTableExpr</a></strong></dt> - <dd> Syntax: <code>GetProcAddressTableExpr [expression]</code> <br/> - - (required) Defines the Java code snippet used by the generated glue - code to fetch the ProcAddressTable containing the function pointers - for the current API. It is up to the user to decide where to store the - ProcAddressTable. Common places for it include in an instance field of - the implementing class, in an associated object with which there is a - one-to-one mapping, or in a static field of another class accessed by - a static method. In the JOGL project, for example, each GLImpl - instance has an associated GLContext in an instance field called - "_context", so the associated directive is - <code>GetProcAddressTableExpr _context.getGLProcAddressTable()</code>. - In the JOAL project, the ProcAddressTables are currently held in a - separate class accessed via static methods, so one of the associated - directives is <code>GetProcAddressTableExpr - ALProcAddressLookup.getALCProcAddressTable()</code>. - </dd> - - <dt><strong><a name="ProcAddressNameExpr">ProcAddressNameExpr</a></strong></dt> - <dd> Syntax: <code>ProcAddressNameExpr [expression]</code> <br/> - - (required) Defines the mapping from function name to function pointer - typedef to be able to properly identify this function as needing - call-through-function-pointer semantics. The supplied expression uses - a set of simple commands to describe certain operations on the - function name: - - <ul> - <li> <code>$UpperCase(arg)</code> converts the argument to - uppercase. "UpperCase" is case-insensitive.</li> - <li> <code>$LowerCase(arg)</code> converts the argument to - lowercase. "LowerCase" is case-insensitive.</li> - <li> <code>{0}</code> represents the name of the function.</li> - <li> Any other string represents a constant string.</li> - <li> Concatenation is implicit.</li> - </ul> - - The corresponding ProcAddressNameExpr for the OpenGL extension - functions as described at the start of this section is <code>PFN - $UPPERCASE({0}) PROC</code>. The ProcAddressNameExpr for the OpenAL - functions as described at the start of this section is <code>LP - $UPPERCASE({0})</code>. - </dd> - - <dt><strong><a name="ProcAddressTableClassName">ProcAddressTableClassName</a></strong></dt> - <dd> Syntax: <code>ProcAddressTableClassName [class name]</code> <br/> - - (optional) Specifies the class name into which the table containing - the function pointers will be emitted. Defaults to "ProcAddressTable". - </dd> - - <dt><strong><a name="ProcAddressTablePackage">ProcAddressTablePackage</a></strong></dt> - <dd> Syntax: <code>ProcAddressTablePackage [package name] (no - trailing semicolon)</code> <br/> - - (optional) Specifies the package into which to produce the - ProcAddressTable for the current set of APIs. Defaults to the - implementation package specified by the <a - href="#ImplPackage">ImplPackage</a> directive. - </dd> - - <dt><strong><a name="SkipProcAddressGen">SkipProcAddressGen</a></strong></dt> - <dd> Syntax: <code>SkipProcAddressGen [function name]</code> <br/> - - (optional) Indicates that the default behavior of - call-through-function-pointer should be skipped for this function - despite the fact that it has an associated function pointer typedef in - the header. - </dd> - </dl> - - <h2> <a name="Chapter3">Chapter 3 - Configuration File Examples</a> </h2> - - <h3><a name="SecSimplest">Simplest possible example</a></h3> - - Files: - <ul> - <li> <a href="example1/function.c">function.c</a></li> - <li> <a href="example1/function.h">function.h</a></li> - <li> <a href="example1/function.cfg">function.cfg</a></li> - <li> <a href="example1/gen.sh">gen.sh</a></li> - </ul> - - <p> This example shows the simplest possible usage of GlueGen; a - single routine taking as arguments and returning only primitive - types. The signature of the C function we are interested in binding is - </p> - - <pre> - int one_plus(int a); - </pre> - - <p> To bind this function to Java, we only need a configuration file - with very basic settings, indicating the style of glue code emission, - the package and class into which the glue code will be generated, and - the output directories for the Java and native code. The contents of - the configuration file are as follows: </p> - - <pre> - Package testfunction + typedef void (AL_APIENTRY *LPALENABLE)( ALenum capability );</code></pre> +<p>Therefore the mapping rule between the function name and the function +pointer typedef for the OpenAL header files is "LP + +Uppercase(funcname)".</p> +<p>These are the two principal function pointer-based APIs toward which +the GlueGen tool has currently been applied. It may turn out to be that +this simple mapping heuristic is insufficient, in which case it will +need to be extended in a future version of the GlueGen tool.</p> +<p>Note that it is currently the case that in order for the +ProcAddressEmitter to notice that a given function should be called +through a function pointer, it must see both the function prototype as +well as the function pointer typedef. Some headers, in particular the +OpenAL headers, have their <code>#ifdefs</code> structured in such a way +that either the declaration or the typedef is visible, but not both +simultaneously. Because the <a href="#SecJCPP">JCPP</a> C preprocessor +GlueGen uses obeys <code>#ifdefs</code>, it is in a situation like this +that the headers would have to be modified to allow GlueGen to see both +declarations.</p> +<p>The following directives are specified in alphabetical order, +although this is not necessarily the best semantic order. The +ProcAddressEmitter also accepts all of the directives supported by the +JavaEmitter. The required directives are <a +href="#GetProcAddressTableExpr">GetProcAddressTableExpr</a> and <a +href="#ProcAddressNameExpr">ProcAddressNameExpr</a>.</p> +<p><strong><span id="EmitProcAddressTable">EmitProcAddressTable</span></strong><br /> +Syntax: <code>EmitProcAddressTable [true | false]</code><br /> +(optional) Indicates whether to emit the ProcAddressTable during glue +code generation. Defaults to false.</p> +<p><strong><span id="ForceProcAddressGen">ForceProcAddressGen</span></strong><br /> +Syntax: <code>ForceProcAddressGen [function name]</code><br /> +(optional) Indicates that a ProcAddressTable entry should be produced +for the specified function even though it does not have an associated +function pointer typedef in the header. This directive does not +currently cause the autogenerated Java and C code to change to +call-through-function-pointer style, which should probably be considered +a bug. (FIXME)</p> +<p><strong><span id="GetProcAddressTableExpr">GetProcAddressTableExpr</span></strong><br /> +Syntax: <code>GetProcAddressTableExpr [expression]</code><br /> +(required) Defines the Java code snippet used by the generated glue code +to fetch the ProcAddressTable containing the function pointers for the +current API. It is up to the user to decide where to store the +ProcAddressTable. Common places for it include in an instance field of +the implementing class, in an associated object with which there is a +one-to-one mapping, or in a static field of another class accessed by a +static method. In the JOGL project, for example, each GLImpl instance +has an associated GLContext in an instance field called "_context", so +the associated directive is +<code>GetProcAddressTableExpr _context.getGLProcAddressTable()</code>. +In the JOAL project, the ProcAddressTables are currently held in a +separate class accessed via static methods, so one of the associated +directives is +<code>GetProcAddressTableExpr ALProcAddressLookup.getALCProcAddressTable()</code>.</p> +<p><strong><span id="ProcAddressNameExpr">ProcAddressNameExpr</span></strong><br /> +Syntax: <code>ProcAddressNameExpr [expression]</code><br /> +(required) Defines the mapping from function name to function pointer +typedef to be able to properly identify this function as needing +call-through-function-pointer semantics. The supplied expression uses a +set of simple commands to describe certain operations on the function +name:</p> +<ul> +<li><code>$UpperCase(arg)</code> converts the argument to uppercase. +"UpperCase" is case-insensitive.</li> +<li><code>$LowerCase(arg)</code> converts the argument to lowercase. +"LowerCase" is case-insensitive.</li> +<li><code>{0}</code> represents the name of the function.</li> +<li>Any other string represents a constant string.</li> +<li>Concatenation is implicit.</li> +</ul> +<p>The corresponding ProcAddressNameExpr for the OpenGL extension +functions as described at the start of this section is +<code>PFN $UPPERCASE({0}) PROC</code>. +The ProcAddressNameExpr for the OpenAL functions as described at the +start of this section is +<code>LP $UPPERCASE({0})</code>.</p> +<p><strong><span id="ProcAddressTableClassName">ProcAddressTableClassName</span></strong><br /> +Syntax: <code>ProcAddressTableClassName [class name]</code><br /> +(optional) Specifies the class name into which the table containing the +function pointers will be emitted. Defaults to "ProcAddressTable".</p> +<p><strong><span id="ProcAddressTablePackage">ProcAddressTablePackage</span></strong><br /> +Syntax: +<code>ProcAddressTablePackage [package name] (no trailing semicolon)</code><br /> +(optional) Specifies the package into which to produce the +ProcAddressTable for the current set of APIs. Defaults to the +implementation package specified by the <a +href="#ImplPackage">ImplPackage</a> directive.</p> +<p><strong><span id="SkipProcAddressGen">SkipProcAddressGen</span></strong><br /> +Syntax: <code>SkipProcAddressGen [function name]</code><br /> +(optional) Indicates that the default behavior of +call-through-function-pointer should be skipped for this function +despite the fact that it has an associated function pointer typedef in +the header.</p> +<h2 +id="chapter-3---configuration-file-examples"><span id="Chapter3">Chapter +3 - Configuration File Examples</span></h2> +<h3 id="simplest-possible-example"><span id="SecSimplest">Simplest +possible example</span></h3> +<p>Files:</p> +<ul> +<li><a href="example1/function.c">function.c</a></li> +<li><a href="example1/function.h">function.h</a></li> +<li><a href="example1/function.cfg">function.cfg</a></li> +<li><a href="example1/gen.sh">gen.sh</a></li> +</ul> +<p>This example shows the simplest possible usage of GlueGen; a single +routine taking as arguments and returning only primitive types. The +signature of the C function we are interested in binding is</p> +<pre><code> int one_plus(int a);</code></pre> +<p>To bind this function to Java, we only need a configuration file with +very basic settings, indicating the style of glue code emission, the +package and class into which the glue code will be generated, and the +output directories for the Java and native code. The contents of the +configuration file are as follows:</p> +<pre><code> Package testfunction Style AllStatic JavaClass TestFunction JavaOutputDir gensrc/java - NativeOutputDir gensrc/native - </pre> - - <p> GlueGen can then be invoked with approximately the following - command line: - </p> - - <pre> - java -cp gluegen.jar:antlr.jar com.jogamp.gluegen.GlueGen \ - -I. -Ecom.jogamp.gluegen.JavaEmitter -Cfunction.cfg function.h - </pre> - - <p> The resulting Java and native code needs to be compiled, and the - application needs to load the native library for the Java binding - before attempting to invoke the native method by calling - <code>System.load()</code> or <code>System.loadLibrary()</code>. </p> - - <h3><a name="SecArrays">Arrays and buffers</a></h3> - - Files: - <ul> - <li> <a href="example2/function.c">function.c</a></li> - <li> <a href="example2/function.h">function.h</a></li> - <li> <a href="example2/function.cfg">function.cfg</a></li> - <li> <a href="example2/gen.sh">gen.sh</a></li> - </ul> - - <p> This example shows how C primitive arrays are bound to Java. The - header file contains three functions to bind: </p> - - <pre> - float process_data(float* data, int n); + NativeOutputDir gensrc/native</code></pre> +<p>GlueGen can then be invoked with approximately the following command +line:</p> +<pre><code> java -cp gluegen.jar:antlr.jar com.jogamp.gluegen.GlueGen \ + -I. -Ecom.jogamp.gluegen.JavaEmitter -Cfunction.cfg function.h</code></pre> +<p>The resulting Java and native code needs to be compiled, and the +application needs to load the native library for the Java binding before +attempting to invoke the native method by calling +<code>System.load()</code> or <code>System.loadLibrary()</code>.</p> +<h3 id="arrays-and-buffers"><span id="SecArrays">Arrays and +buffers</span></h3> +<p>Files:</p> +<ul> +<li><a href="example2/function.c">function.c</a></li> +<li><a href="example2/function.h">function.h</a></li> +<li><a href="example2/function.cfg">function.cfg</a></li> +<li><a href="example2/gen.sh">gen.sh</a></li> +</ul> +<p>This example shows how C primitive arrays are bound to Java. The +header file contains three functions to bind:</p> +<pre><code> float process_data(float* data, int n); void set_global_data(float* data); - float process_global_data(int n); - </pre> - - <p> The semantics of <code>process_data</code> are that it takes in a - pointer to a set of primitive <code>float</code> values and the number - of elements in the array and performs some operation on them, - returning a floating-point value as the result. Afterward the passed - data is no longer referenced. - </p> - - <p> <code>set_global_data</code>, on the other hand, takes a pointer - to the data and stores it persistently in the C code. - <code>process_global_data</code> then accepts as argument the number - of elements to process from the previously-set global data, performs - this processing and returns a result. The global data may be accessed - again afterward. As an example, these kinds of semantics are used in - certain places in the OpenGL API. - </p> - - <p> From a Java binding standpoint, <code>process_data</code> may - accept data stored either inside the Java heap (in the form of a - <code>float[]</code> or non-direct <code>FloatBuffer</code>) or - outside the Java heap (in the form of a direct - <code>FloatBuffer</code>), because it does not access the data after - the function call has completed and therefore would not be affected if - garbage collection moved the data after the function call was - complete. However, <code>set_global_data</code> can cause the passed - data to be accessed after the function call is complete, if - <code>process_global_data</code> is called. Therefore the data passed - to <code>set_global_data</code> may not reside in the Java - garbage-collected heap, but must reside outside the heap in the form - of a direct <code>FloatBuffer</code>. - </p> - - <p> It is straightforward to take into account these differences in - semantics in the configuration file using the <a - href="#NioDirectOnly">NioDirectOnly</a> directive: - </p> - - <pre> - # The semantics of set_global_data imply that + float process_global_data(int n);</code></pre> +<p>The semantics of <code>process_data</code> are that it takes in a +pointer to a set of primitive <code>float</code> values and the number +of elements in the array and performs some operation on them, returning +a floating-point value as the result. Afterward the passed data is no +longer referenced.</p> +<p><code>set_global_data</code>, on the other hand, takes a pointer to +the data and stores it persistently in the C code. +<code>process_global_data</code> then accepts as argument the number of +elements to process from the previously-set global data, performs this +processing and returns a result. The global data may be accessed again +afterward. As an example, these kinds of semantics are used in certain +places in the OpenGL API.</p> +<p>From a Java binding standpoint, <code>process_data</code> may accept +data stored either inside the Java heap (in the form of a +<code>float[]</code> or non-direct <code>FloatBuffer</code>) or outside +the Java heap (in the form of a direct <code>FloatBuffer</code>), +because it does not access the data after the function call has +completed and therefore would not be affected if garbage collection +moved the data after the function call was complete. However, +<code>set_global_data</code> can cause the passed data to be accessed +after the function call is complete, if <code>process_global_data</code> +is called. Therefore the data passed to <code>set_global_data</code> may +not reside in the Java garbage-collected heap, but must reside outside +the heap in the form of a direct <code>FloatBuffer</code>.</p> +<p>It is straightforward to take into account these differences in +semantics in the configuration file using the <a +href="#NioDirectOnly">NioDirectOnly</a> directive:</p> +<pre><code> # The semantics of set_global_data imply that # only direct Buffers are legal - NioDirectOnly set_global_data - </pre> - - <p> Note the differences in the generated Java-side overloadings for - the two functions: - </p> - - <pre> - public static void process_data(java.nio.FloatBuffer data, int n) {...} + NioDirectOnly set_global_data</code></pre> +<p>Note the differences in the generated Java-side overloadings for the +two functions:</p> +<pre><code> public static void process_data(java.nio.FloatBuffer data, int n) {...} public static void process_data(float[] data, int data_offset, int n) {...} - public static void set_global_data(java.nio.FloatBuffer data) {...} - </pre> - - <p> - No overloading is produced for <code>set_global_data</code> taking - a <code>float[]</code>, as it can not handle data residing in the Java - heap. Further, the generated glue code will verify that any - <code>FloatBuffer</code> passed to this routine is direct, throwing a - <code>RuntimeException</code> if not. The type of the exception thrown - in this and other cases may be changed with the <a - href="#RuntimeExceptionType">RuntimeExceptionType</a> directive. - </p> - - <h3><a name="SecString">String handling</a></h3> - - Files: - <ul> - <li> <a href="example3/function.h">function.h</a></li> - <li> <a href="example3/function.cfg">function.cfg</a></li> - <li> <a href="example3/gen.sh">gen.sh</a></li> - </ul> - <p> This example shows how to pass and return C strings. The functions - involved are a bit contrived, as nobody would ever need to bind the C - library's string handling routines to Java, but they do illustrate - situations in which Java strings might need to be passed to C and C - strings returned to Java. As an example, both styles of function are - present in the OpenGL and OpenAL APIs. - </p> - - <p> The included source code exposes two functions to Java: </p> - - <pre> - size_t strlen(const char* str); - char* strstr(const char* str1, const char* str2); - </pre> - - <p> Note that we might just as easily parse the C standard library's - <code>string.h</code> header file to pick up these function - declarations. However for the purposes of this example it is easier to - extract just the functions we need. - </p> - - <p> Note that the <a href="example3/function.h">function.h</a> header - file contains a typedef for <code>size_t</code>. This is needed - because GlueGen does not inherently know about this data type. An - equivalent data type for the purposes of this example is - <code>int</code>, so we choose to tell GlueGen to use that data type - in place of <code>size_t</code> while generating glue code. - </p> - - <p> The following directive in the configuration file tells GlueGen - that <code>strlen</code> takes a string as argument 0 (the first - argument): - </p> - - <pre> - ArgumentIsString strlen 0 - </pre> - - <p> The following directive tells GlueGen that <code>strstr</code> - takes two strings as its arguments: </p> - - <pre> - ArgumentIsString strstr 0 1 - </pre> - - <p> Finally, the following directive tells GlueGen that - <code>strstr</code> returns a string instead of an array of bytes: - </p> - - <pre> - ReturnsString strstr - </pre> - - <p> We also use the <a href="#CustomCCode">CustomCCode</a> directive - to cause the <code>string.h</code> header file to be #included in the - generated glue code: - </p> - - <pre> - CustomCCode /* Include string.h header */ - CustomCCode #include <string.h> - </pre> - - <p> Now the bindings of these two functions to Java look as expected:</p> - - <pre> - public static native int strlen(java.lang.String str); - public static native java.lang.String strstr(java.lang.String str1, java.lang.String str2); - </pre> - - Note that the <a href="#ReturnsString">ReturnsString</a> directive - does not currently correctly handle the case where the - <code>char*</code> returned from C needs to be explicitly freed. As an - example, a binding of the C function <code>strdup</code> using a - ReturnsString directive would cause a C heap memory leak. - - <h3><a name="SecMemory">Memory allocation</a></h3> - - Files: - <ul> - <li> <a href="example4/function.c">function.c</a></li> - <li> <a href="example4/function.h">function.h</a></li> - <li> <a href="example4/function.cfg">function.cfg</a></li> - <li> <a href="example4/gen.sh">gen.sh</a></li> - </ul> - - <p> This example shows how memory allocation is handled when binding C - to Java. It gives the example of a custom memory allocator being bound - to Java; this is a construct that at least at one point was present in - OpenGL in the NV_vertex_array_range extension. </p> - - <p> The two functions we are exposing to Java are as follows: </p> - <pre> - void* custom_allocate(int num_bytes); - void custom_free(void* data); - </pre> - - <p> The Java-side return type of <code>custom_allocate</code> will - necessarily be a <code>ByteBuffer</code>, as that is the only useful - way of interacting with arbitrary memory produced by C. The question - is how to inform the glue code generator of the size of the returned - sequence of memory. The semantics of <code>custom_allocate</code> are - obvious to the programmer; the incoming <code>num_bytes</code> - argument specifies the amount of returned memory. We tell GlueGen this - fact using the <a href="#ReturnValueCapacity">ReturnValueCapacity</a> - directive: </p> - - <pre> - # The length of the returned ByteBuffer from custom_allocate is + public static void set_global_data(java.nio.FloatBuffer data) {...}</code></pre> +<p>No overloading is produced for <code>set_global_data</code> taking a +<code>float[]</code>, as it can not handle data residing in the Java +heap. Further, the generated glue code will verify that any +<code>FloatBuffer</code> passed to this routine is direct, throwing a +<code>RuntimeException</code> if not. The type of the exception thrown +in this and other cases may be changed with the <a +href="#RuntimeExceptionType">RuntimeExceptionType</a> directive.</p> +<h3 id="string-handling"><span id="SecString">String +handling</span></h3> +<p>Files:</p> +<ul> +<li><a href="example3/function.h">function.h</a></li> +<li><a href="example3/function.cfg">function.cfg</a></li> +<li><a href="example3/gen.sh">gen.sh</a></li> +</ul> +<p>This example shows how to pass and return C strings. The functions +involved are a bit contrived, as nobody would ever need to bind the C +library's string handling routines to Java, but they do illustrate +situations in which Java strings might need to be passed to C and C +strings returned to Java. As an example, both styles of function are +present in the OpenGL and OpenAL APIs.</p> +<p>The included source code exposes two functions to Java:</p> +<pre><code> size_t strlen(const char* str); + char* strstr(const char* str1, const char* str2);</code></pre> +<p>Note that we might just as easily parse the C standard library's +<code>string.h</code> header file to pick up these function +declarations. However for the purposes of this example it is easier to +extract just the functions we need.</p> +<p>Note that the <a href="example3/function.h">function.h</a> header +file contains a typedef for <code>size_t</code>. This is needed because +GlueGen does not inherently know about this data type. An equivalent +data type for the purposes of this example is <code>int</code>, so we +choose to tell GlueGen to use that data type in place of +<code>size_t</code> while generating glue code.</p> +<p>The following directive in the configuration file tells GlueGen that +<code>strlen</code> takes a string as argument 0 (the first +argument):</p> +<pre><code> ArgumentIsString strlen 0</code></pre> +<p>The following directive tells GlueGen that <code>strstr</code> takes +two strings as its arguments:</p> +<pre><code> ArgumentIsString strstr 0 1</code></pre> +<p>Finally, the following directive tells GlueGen that +<code>strstr</code> returns a string instead of an array of bytes:</p> +<pre><code> ReturnsString strstr</code></pre> +<p>We also use the <a href="#CustomCCode">CustomCCode</a> directive to +cause the <code>string.h</code> header file to be #included in the +generated glue code:</p> +<pre><code> CustomCCode /* Include string.h header */ + CustomCCode #include <string.h></code></pre> +<p>Now the bindings of these two functions to Java look as expected:</p> +<pre><code> public static native int strlen(java.lang.String str); + public static native java.lang.String strstr(java.lang.String str1, java.lang.String str2);</code></pre> +<p>Note that the <a href="#ReturnsString">ReturnsString</a> directive +does not currently correctly handle the case where the +<code>char*</code> returned from C needs to be explicitly freed. As an +example, a binding of the C function <code>strdup</code> using a +ReturnsString directive would cause a C heap memory leak.</p> +<h3 id="memory-allocation"><span id="SecMemory">Memory +allocation</span></h3> +<p>Files:</p> +<ul> +<li><a href="example4/function.c">function.c</a></li> +<li><a href="example4/function.h">function.h</a></li> +<li><a href="example4/function.cfg">function.cfg</a></li> +<li><a href="example4/gen.sh">gen.sh</a></li> +</ul> +<p>This example shows how memory allocation is handled when binding C to +Java. It gives the example of a custom memory allocator being bound to +Java; this is a construct that at least at one point was present in +OpenGL in the NV_vertex_array_range extension.</p> +<p>The two functions we are exposing to Java are as follows:</p> +<pre><code> void* custom_allocate(int num_bytes); + void custom_free(void* data);</code></pre> +<p>The Java-side return type of <code>custom_allocate</code> will +necessarily be a <code>ByteBuffer</code>, as that is the only useful way +of interacting with arbitrary memory produced by C. The question is how +to inform the glue code generator of the size of the returned sequence +of memory. The semantics of <code>custom_allocate</code> are obvious to +the programmer; the incoming <code>num_bytes</code> argument specifies +the amount of returned memory. We tell GlueGen this fact using the <a +href="#ReturnValueCapacity">ReturnValueCapacity</a> directive:</p> +<pre><code> # The length of the returned ByteBuffer from custom_allocate is # specified as the argument - ReturnValueCapacity custom_allocate {0} - </pre> - - <p> Note that we name incoming argument 0 with the MessageFormat - specifier "{0}" rather than the explicit name of the parameter - ("num_bytes") for generality, in case the header file is changed - later. - </p> - - <p> Because <code>custom_free</code> will only ever receive Buffers - produced by custom_allocate, we use the <a - href="#NioDirectOnly">NioDirectOnly</a> directive to prevent - accidental usage with the wrong kind of Buffer: </p> - - <pre> - # custom_free will only ever receive a direct Buffer - NioDirectOnly custom_free - </pre> - - <p> The generated Java APIs for these functions are as follows: </p> - - <pre> - public static java.nio.ByteBuffer custom_allocate(int num_bytes) {...} - public static void custom_free(java.nio.Buffer data) {...} - </pre> - - <h3><a name="SecStructs">Ingoing and outgoing structs</a></h3> - - Files: - <ul> - <li> <a href="example5/function.c">function.c</a></li> - <li> <a href="example5/function.h">function.h</a></li> - <li> <a href="example5/function.cfg">function.cfg</a></li> - <li> <a href="example5/gen.sh">gen.sh</a></li> - </ul> - - <p> This example shows how GlueGen provides access to C structs and - supports both passing them to and returning them from C functions. The - header file defines a sample data structure that might describe the - bit depth of a given screen: </p> - - <pre> - typedef struct { + ReturnValueCapacity custom_allocate {0}</code></pre> +<p>Note that we name incoming argument 0 with the MessageFormat +specifier "{0}" rather than the explicit name of the parameter +("num_bytes") for generality, in case the header file is changed +later.</p> +<p>Because <code>custom_free</code> will only ever receive Buffers +produced by custom_allocate, we use the <a +href="#NioDirectOnly">NioDirectOnly</a> directive to prevent accidental +usage with the wrong kind of Buffer:</p> +<pre><code> # custom_free will only ever receive a direct Buffer + NioDirectOnly custom_free</code></pre> +<p>The generated Java APIs for these functions are as follows:</p> +<pre><code> public static java.nio.ByteBuffer custom_allocate(int num_bytes) {...} + public static void custom_free(java.nio.Buffer data) {...}</code></pre> +<h3 id="ingoing-and-outgoing-structs"><span id="SecStructs">Ingoing and +outgoing structs</span></h3> +<p>Files:</p> +<ul> +<li><a href="example5/function.c">function.c</a></li> +<li><a href="example5/function.h">function.h</a></li> +<li><a href="example5/function.cfg">function.cfg</a></li> +<li><a href="example5/gen.sh">gen.sh</a></li> +</ul> +<p>This example shows how GlueGen provides access to C structs and +supports both passing them to and returning them from C functions. The +header file defines a sample data structure that might describe the bit +depth of a given screen:</p> +<pre><code> typedef struct { int redBits; int greenBits; int blueBits; - } ScreenInfo; - </pre> - - <p> Two functions are defined which take and return this data type: - </p> - - <pre> - ScreenInfo* default_screen_depth(); - void set_screen_depth(ScreenInfo* info); - </pre> - - <p> The semantics of <code>default_screen_depth()</code> are that it - returns a pointer to some static storage which does not need to be - freed, which describes the default screen depth. - <code>set_screen_depth()</code> is a hypothetical function which would - take a newly-allocated <code>ScreenInfo</code> and cause the primary - display to switch to the specified bit depth. </p> - - <p> The only additional information we need to tell GlueGen, beyond - that in the header file, is how much storage is returned from - <code>default_screen_depth()</code>. Note the semantic ambiguity, - where it might return a pointer to a single <code>ScreenInfo</code> or - a pointer to an array of <code>ScreenInfo</code>s. We tell GlueGen - that the return value is a single value with the <a - href="#ReturnValueCapacity">ReturnValueCapacity</a> directive, - similarly to the <a href="#SecMemory">memory allocation</a> example - above: </p> - - <pre> - # Tell GlueGen that default_screen_depth() returns a pointer to a + } ScreenInfo;</code></pre> +<p>Two functions are defined which take and return this data type:</p> +<pre><code> ScreenInfo* default_screen_depth(); + void set_screen_depth(ScreenInfo* info);</code></pre> +<p>The semantics of <code>default_screen_depth()</code> are that it +returns a pointer to some static storage which does not need to be +freed, which describes the default screen depth. +<code>set_screen_depth()</code> is a hypothetical function which would +take a newly-allocated <code>ScreenInfo</code> and cause the primary +display to switch to the specified bit depth.</p> +<p>The only additional information we need to tell GlueGen, beyond that +in the header file, is how much storage is returned from +<code>default_screen_depth()</code>. Note the semantic ambiguity, where +it might return a pointer to a single <code>ScreenInfo</code> or a +pointer to an array of <code>ScreenInfo</code>s. We tell GlueGen that +the return value is a single value with the <a +href="#ReturnValueCapacity">ReturnValueCapacity</a> directive, similarly +to the <a href="#SecMemory">memory allocation</a> example above:</p> +<pre><code> # Tell GlueGen that default_screen_depth() returns a pointer to a # single ScreenInfo - ReturnValueCapacity default_screen_depth sizeof(ScreenInfo) - </pre> - - <p> Note that if <code>default_screen_depth</code> had returned - newly-allocated storage, it would be up to the user to expose a - <code>free()</code> function to Java and call it when necessary. </p> - - <p> GlueGen automatically generates a Java-side - <code>ScreenInfo</code> class which supports not only access to any - such objects returned from C, but also allocation of new - <code>ScreenInfo</code> structs which can be passed (persistently) - down to C. The Java API for the ScreenInfo class looks like this: </p> - - <pre> - public abstract class ScreenInfo { + ReturnValueCapacity default_screen_depth sizeof(ScreenInfo)</code></pre> +<p>Note that if <code>default_screen_depth</code> had returned +newly-allocated storage, it would be up to the user to expose a +<code>free()</code> function to Java and call it when necessary.</p> +<p>GlueGen automatically generates a Java-side <code>ScreenInfo</code> +class which supports not only access to any such objects returned from +C, but also allocation of new <code>ScreenInfo</code> structs which can +be passed (persistently) down to C. The Java API for the ScreenInfo +class looks like this:</p> +<pre><code> public abstract class ScreenInfo { public static ScreenInfo create(); public abstract ScreenInfo redBits(int val); public abstract int redBits(); ... - } - </pre> - - <p> The <code>create()</code> method allocates a new ScreenInfo struct - which may be passed, even persistently, out to C. Its C-heap storage - will be automatically reclaimed when the Java-side ScreenInfo object - is no longer reachable, as it is backed by a direct New I/O - <code>ByteBuffer</code>. The fields of the struct are exposed as - methods which supply both getters and setters. </p> - - <h3><a name="SecStructArrays">Returned arrays of structs</a></h3> - - Files: - <ul> - <li> <a href="example6/function.h">function.h</a></li> - <li> <a href="example6/function.cfg">function.cfg</a></li> - <li> <a href="example6/gen.sh">gen.sh</a></li> - </ul> - - <p> This example, taken from JOGL's X11 binding, illustrates how to - return an array of structs from C to Java. The - <code>XGetVisualInfo</code> function from the X library has the - following signature: </p> - - <pre> - XVisualInfo *XGetVisualInfo( + }</code></pre> +<p>The <code>create()</code> method allocates a new ScreenInfo struct +which may be passed, even persistently, out to C. Its C-heap storage +will be automatically reclaimed when the Java-side ScreenInfo object is +no longer reachable, as it is backed by a direct New I/O +<code>ByteBuffer</code>. The fields of the struct are exposed as methods +which supply both getters and setters.</p> +<h3 id="returned-arrays-of-structs"><span id="SecStructArrays">Returned +arrays of structs</span></h3> +<p>Files:</p> +<ul> +<li><a href="example6/function.h">function.h</a></li> +<li><a href="example6/function.cfg">function.cfg</a></li> +<li><a href="example6/gen.sh">gen.sh</a></li> +</ul> +<p>This example, taken from JOGL's X11 binding, illustrates how to +return an array of structs from C to Java. The +<code>XGetVisualInfo</code> function from the X library has the +following signature:</p> +<pre><code> XVisualInfo *XGetVisualInfo( Display* display, long vinfo_mask, XVisualInfo* vinfo_template, int* nitems_return - ); - </pre> - - <p> Note that the <code>XVisualInfo</code> data structure itself - contains many elements, including a pointer to the current visual. We - use the following trick in the header file to cause GlueGen to treat - the <code>Display*</code> in the above signature as well as the - <code>Visual*</code> in the <code>XVisualInfo</code> as opaque - pointers: </p> - - <pre> - typedef struct {} Display; + );</code></pre> +<p>Note that the <code>XVisualInfo</code> data structure itself contains +many elements, including a pointer to the current visual. We use the +following trick in the header file to cause GlueGen to treat the +<code>Display*</code> in the above signature as well as the +<code>Visual*</code> in the <code>XVisualInfo</code> as opaque +pointers:</p> +<pre><code> typedef struct {} Display; typedef struct {} Visual; typedef unsigned long VisualID; @@ -2136,148 +1968,115 @@ unsigned long blue_mask; int colormap_size; int bits_per_rgb; - } XVisualInfo; - </pre> - - <p> <code>XGetVisualInfo</code> returns all of the available pixel - formats in the form of <code>XVisualInfo</code>s which match a given - template. <code>display</code> is the current connection to the X - server. <code>vinfo_mask</code> indicates which fields from the - template to match against. <code>vinfo_template</code> is a partially - filled-in <code>XVisualInfo</code> specifying the characteristics to - match. <code>nitems_return</code> is a pointer to an integer - indicating how many <code>XVisualInfo</code>s were returned. The - return value, rather than being a pointer to a single - <code>XVisualInfo</code>, is a pointer to the start of an array of - <code>XVisualInfo</code> data structures. </p> - - <p> There are two basic steps to being able to return this array - properly to Java using GlueGen. The first is creating a direct - ByteBuffer of the appropriate size in the autogenerated JNI code. The - second is slicing up this ByteBuffer appropriately in order to return - an <code>XVisualInfo[]</code> at the Java level. </p> - - <p> In the autogenerated JNI code, after the call to - <code>XGetVisualInfo</code> is made, the outgoing - <code>nitems_return</code> value points to the number of elements in - the returned array, which indicates the size of the direct ByteBuffer - which would need to wrap these elements. However, if we look at the - implementation of one of the generated glue code variants for this - method (specifically, the one taking an <code>int[]</code> as the - third argument), we can see a problem in trying to access this value - in the C code: </p> - - <pre> - JNIEXPORT jobject JNICALL + } XVisualInfo;</code></pre> +<p><code>XGetVisualInfo</code> returns all of the available pixel +formats in the form of <code>XVisualInfo</code>s which match a given +template. <code>display</code> is the current connection to the X +server. <code>vinfo_mask</code> indicates which fields from the template +to match against. <code>vinfo_template</code> is a partially filled-in +<code>XVisualInfo</code> specifying the characteristics to match. +<code>nitems_return</code> is a pointer to an integer indicating how +many <code>XVisualInfo</code>s were returned. The return value, rather +than being a pointer to a single <code>XVisualInfo</code>, is a pointer +to the start of an array of <code>XVisualInfo</code> data +structures.</p> +<p>There are two basic steps to being able to return this array properly +to Java using GlueGen. The first is creating a direct ByteBuffer of the +appropriate size in the autogenerated JNI code. The second is slicing up +this ByteBuffer appropriately in order to return an +<code>XVisualInfo[]</code> at the Java level.</p> +<p>In the autogenerated JNI code, after the call to +<code>XGetVisualInfo</code> is made, the outgoing +<code>nitems_return</code> value points to the number of elements in the +returned array, which indicates the size of the direct ByteBuffer which +would need to wrap these elements. However, if we look at the +implementation of one of the generated glue code variants for this +method (specifically, the one taking an <code>int[]</code> as the third +argument), we can see a problem in trying to access this value in the C +code:</p> +<pre><code> JNIEXPORT jobject JNICALL Java_testfunction_TestFunction_XGetVisualInfo1__Ljava_nio_ByteBuffer_2JLjava_nio_ByteBuffer_2Ljava_lang_Object_2I( JNIEnv *env, jclass _unused, jobject arg0, jlong arg1, jobject arg2, jobject arg3, jint arg3_byte_offset) { ... int * _ptr3 = NULL; ... if (arg3 != NULL) { - _ptr3 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, arg3, NULL)) + arg3_byte_offset); + _ptr3 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, arg3, NULL)) + arg3_byte_offset); } _res = XGetVisualInfo((Display *) _ptr0, (long) arg1, (XVisualInfo *) _ptr2, (int *) _ptr3); if (arg3 != NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, arg3, _ptr3, 0); + (*env)->ReleasePrimitiveArrayCritical(env, arg3, _ptr3, 0); } if (_res == NULL) return NULL; - return (*env)->NewDirectByteBuffer(env, _res, ??? What to put here ???); - } - </pre> - - <p> Note that at the point of the statement "What to put here?" the - pointer to the storage of the <code>int[]</code>, <code>_ptr3</code>, - has already been released via - <code>ReleasePrimitiveArrayCritical</code>. This means that it may not - be referenced at the point needed in the code. </p> - - <p> To solve this problem we use the <a - href="#TemporaryCVariableDeclaration">TemporaryCVariableDeclaration</a> - and <a - href="#TemporaryCVariableAssignment">TemporaryCVariableAssignment</a> - directives. We want to declare a persistent integer variable down in - the C code and assign the returned array length to that variable - before the primitive array is released. While in order to do this we - unfortunately need to know something about the structure of the - autogenerated JNI code, at least we don't have to hand-edit it - afterward. We add the following directives to the configuration file: </p> - - <pre> - # Get returned array's capacity from XGetVisualInfo to be correct + return (*env)->NewDirectByteBuffer(env, _res, ??? What to put here ???); + }</code></pre> +<p>Note that at the point of the statement "What to put here?" the +pointer to the storage of the <code>int[]</code>, <code>_ptr3</code>, +has already been released via +<code>ReleasePrimitiveArrayCritical</code>. This means that it may not +be referenced at the point needed in the code.</p> +<p>To solve this problem we use the <a +href="#TemporaryCVariableDeclaration">TemporaryCVariableDeclaration</a> +and <a +href="#TemporaryCVariableAssignment">TemporaryCVariableAssignment</a> +directives. We want to declare a persistent integer variable down in the +C code and assign the returned array length to that variable before the +primitive array is released. While in order to do this we unfortunately +need to know something about the structure of the autogenerated JNI +code, at least we don't have to hand-edit it afterward. We add the +following directives to the configuration file:</p> +<pre><code> # Get returned array's capacity from XGetVisualInfo to be correct TemporaryCVariableDeclaration XGetVisualInfo int count; - TemporaryCVariableAssignment XGetVisualInfo count = _ptr3[0]; - </pre> - - <p> Now in the autogenerated JNI code the variable "count" will - contain the number of elements in the returned array. We can then - reference this variable in a <a - href="#ReturnValueCapacity">ReturnValueCapacity</a> directive: </p> - - <pre> - ReturnValueCapacity XGetVisualInfo count * sizeof(XVisualInfo) - </pre> - - <p> At this point the <code>XGetVisualInfo</code> binding will return - a Java-side <code>XVisualInfo</code> object whose backing ByteBuffer - is the correct size. We now have to inform GlueGen that the underlying - ByteBuffer represents not a single <code>XGetVisualInfo</code> struct, - but an array of them, using the <a - href="#ReturnedArrayLength">ReturnedArrayLength</a> directive. This - conversion is performed on the Java side of the autogenerated code. - Here, the first element of either the passed <code>IntBuffer</code> or - <code>int[]</code> contains the number of elements in the returned - array. (Alternatively, we could examine the length of the ByteBuffer - returned from C to Java and divide by - <code>XVisualInfo.size()</code>.) Because there are two overloadings - produced by GlueGen for this method, if we reference the - <code>nitems_return</code> argument in a <a - href="#ReturnedArrayLength">ReturnedArrayLength</a> directive, we need - to handle not only the differing data types properly - (<code>IntBuffer</code> vs. <code>int[]</code>), but also the fact - that both the integer array and its offset value are substituted for - any reference to the fourth argument. </p> - - <p> To solve this problem, we define a pair of private helper - functions whose purpose is to handle this overloading. </p> - - <pre> - CustomJavaCode TestFunction private static int getFirstElement(IntBuffer buf) { + TemporaryCVariableAssignment XGetVisualInfo count = _ptr3[0];</code></pre> +<p>Now in the autogenerated JNI code the variable "count" will contain +the number of elements in the returned array. We can then reference this +variable in a <a href="#ReturnValueCapacity">ReturnValueCapacity</a> +directive:</p> +<pre><code> ReturnValueCapacity XGetVisualInfo count * sizeof(XVisualInfo)</code></pre> +<p>At this point the <code>XGetVisualInfo</code> binding will return a +Java-side <code>XVisualInfo</code> object whose backing ByteBuffer is +the correct size. We now have to inform GlueGen that the underlying +ByteBuffer represents not a single <code>XGetVisualInfo</code> struct, +but an array of them, using the <a +href="#ReturnedArrayLength">ReturnedArrayLength</a> directive. This +conversion is performed on the Java side of the autogenerated code. +Here, the first element of either the passed <code>IntBuffer</code> or +<code>int[]</code> contains the number of elements in the returned +array. (Alternatively, we could examine the length of the ByteBuffer +returned from C to Java and divide by <code>XVisualInfo.size()</code>.) +Because there are two overloadings produced by GlueGen for this method, +if we reference the <code>nitems_return</code> argument in a <a +href="#ReturnedArrayLength">ReturnedArrayLength</a> directive, we need +to handle not only the differing data types properly +(<code>IntBuffer</code> vs. <code>int[]</code>), but also the fact that +both the integer array and its offset value are substituted for any +reference to the fourth argument.</p> +<p>To solve this problem, we define a pair of private helper functions +whose purpose is to handle this overloading.</p> +<pre><code> CustomJavaCode TestFunction private static int getFirstElement(IntBuffer buf) { CustomJavaCode TestFunction return buf.get(buf.position()); CustomJavaCode TestFunction } CustomJavaCode TestFunction private static int getFirstElement(int[] arr, CustomJavaCode TestFunction int offset) { CustomJavaCode TestFunction return arr[offset]; - CustomJavaCode TestFunction } - </pre> - - <p> Now we can simply write for the returned array length: </p> - - <pre> - ReturnedArrayLength XGetVisualInfo getFirstElement({3}) - </pre> - - <p> That's all that is necessary. GlueGen will then produce the - following Java-side overloadings for this function: </p> - - <pre> - public static XVisualInfo[] XGetVisualInfo(Display arg0, + CustomJavaCode TestFunction }</code></pre> +<p>Now we can simply write for the returned array length:</p> +<pre><code> ReturnedArrayLength XGetVisualInfo getFirstElement({3})</code></pre> +<p>That's all that is necessary. GlueGen will then produce the following +Java-side overloadings for this function:</p> +<pre><code> public static XVisualInfo[] XGetVisualInfo(Display arg0, long arg1, XVisualInfo arg2, java.nio.IntBuffer arg3); public static XVisualInfo[] XGetVisualInfo(Display arg0, long arg1, XVisualInfo arg2, - int[] arg3, int arg3_offset); - </pre> - - <p> As it happens, we don't really need the Display and Visual data - structures to be produced; they can be treated as <code>long</code>s - on the Java side. Therefore we can add the following directives to the - configuration file: </p> - - <pre> - # We don't need the Display and Visual data structures to be + int[] arg3, int arg3_offset);</code></pre> +<p>As it happens, we don't really need the Display and Visual data +structures to be produced; they can be treated as <code>long</code>s on +the Java side. Therefore we can add the following directives to the +configuration file:</p> +<pre><code> # We don't need the Display and Visual data structures to be # explicitly exposed Opaque long Display * Opaque long Visual * @@ -2285,116 +2084,80 @@ # opaque, the references from XVisualInfo and elsewhere are still # traversed) Ignore Display - Ignore Visual - </pre> - - <p> The final generated Java API is the following: </p> - - <pre> - public static XVisualInfo[] XGetVisualInfo(long arg0, + Ignore Visual</code></pre> +<p>The final generated Java API is the following:</p> +<pre><code> public static XVisualInfo[] XGetVisualInfo(long arg0, long arg1, XVisualInfo arg2, java.nio.IntBuffer arg3); public static XVisualInfo[] XGetVisualInfo(long arg0, long arg1, XVisualInfo arg2, - int[] arg3, int arg3_offset); - </pre> - - <h3><a name="SecPointerArrays">Returned arrays of pointers</a></h3> - - Files: - <ul> - <li> <a href="example7/function.h">function.h</a></li> - <li> <a href="example7/function.cfg">function.cfg</a></li> - <li> <a href="example7/gen.sh">gen.sh</a></li> - </ul> - - <p> As with the <a href="#SecStructArrays">example above</a>, this - example is taken from JOGL's X11 binding. Here we show how to expose - to Java a C routine returning an array of pointers to a data - structure. </p> - - <p> The declaration of the function we are binding is as follows: </p> - - <pre> - typedef struct __GLXFBConfigRec *GLXFBConfig; + int[] arg3, int arg3_offset);</code></pre> +<h3 +id="returned-arrays-of-pointers"><span id="SecPointerArrays">Returned +arrays of pointers</span></h3> +<p>Files:</p> +<ul> +<li><a href="example7/function.h">function.h</a></li> +<li><a href="example7/function.cfg">function.cfg</a></li> +<li><a href="example7/gen.sh">gen.sh</a></li> +</ul> +<p>As with the <a href="#SecStructArrays">example above</a>, this +example is taken from JOGL's X11 binding. Here we show how to expose to +Java a C routine returning an array of pointers to a data structure.</p> +<p>The declaration of the function we are binding is as follows:</p> +<pre><code> typedef struct __GLXFBConfigRec *GLXFBConfig; GLXFBConfig *glXChooseFBConfig( Display *dpy, int screen, - const int *attribList, int *nitems ); - </pre> - - <p> This function is used during allocation of a hardware-accelerated - off-screen surface ("pbuffer") on X11 platforms; its exact meaning is - not important. The semantics of the arguments and return value are as - follows. As in the <a href="#SecStructArrays">previous example</a>, it - accepts a connection to the current X display as one argument. The - screen of this display is the second argument. The - <code>attribList</code> is a zero-terminated list of integer - attributes; because it is zero-terminated, the length of this list is - not passed to the function. As in the previous example, the - <code>nitems</code> argument points to an integer into which the - number of returned <code>GLXFBConfig</code> objects is placed. The - return value is an array of <code>GLXFBConfig</code> objects. </p> - - <p> Because the <code>GLXFBConfig</code> data type is typedefed as a - pointer to an opaque (undefined) struct, the construct - <code>GLXFBConfig*</code> is implicitly a "pointer-to-pointer" type. - GlueGen automatically assumes this is convertible to a Java-side array - of accessors to structs. The only configuration necessary is to tell - GlueGen the length of this array. </p> - - <p> As in the previous example, we use the <a - href="#TemporaryCVariableDeclaration">TemporaryCVariableDeclaration</a> - and <a - href="#TemporaryCVariableAssignment">TemporaryCVariableAssignment</a> - directives to capture the length of the returned array: </p> - - TemporaryCVariableDeclaration glXChooseFBConfig int count; - TemporaryCVariableAssignment glXChooseFBConfig count = _ptr3[0]; - - <p> The structure of the generated glue code for the return value is - subtly different than in the previous example. The question in this - case is not whether the return value is a pointer to a single object - vs. a pointer to an array of objects; it is what the length of the - returned array is, since we already know that the return type is - pointer-to-pointer and is therefore an array. We use the <a - href="#ReturnValueLength">ReturnValueLength</a> directive for this - case: </p> - - <pre> - ReturnValueLength glXChooseFBConfig count - </pre> - - We add similar Opaque directives to the previous example to yield the - resulting Java bindings for this function: - - <pre> - public static GLXFBConfig[] glXChooseFBConfig(long dpy, + const int *attribList, int *nitems );</code></pre> +<p>This function is used during allocation of a hardware-accelerated +off-screen surface ("pbuffer") on X11 platforms; its exact meaning is +not important. The semantics of the arguments and return value are as +follows. As in the <a href="#SecStructArrays">previous example</a>, it +accepts a connection to the current X display as one argument. The +screen of this display is the second argument. The +<code>attribList</code> is a zero-terminated list of integer attributes; +because it is zero-terminated, the length of this list is not passed to +the function. As in the previous example, the <code>nitems</code> +argument points to an integer into which the number of returned +<code>GLXFBConfig</code> objects is placed. The return value is an array +of <code>GLXFBConfig</code> objects.</p> +<p>Because the <code>GLXFBConfig</code> data type is typedefed as a +pointer to an opaque (undefined) struct, the construct +<code>GLXFBConfig*</code> is implicitly a "pointer-to-pointer" type. +GlueGen automatically assumes this is convertible to a Java-side array +of accessors to structs. The only configuration necessary is to tell +GlueGen the length of this array.</p> +<p>As in the previous example, we use the <a +href="#TemporaryCVariableDeclaration">TemporaryCVariableDeclaration</a> +and <a +href="#TemporaryCVariableAssignment">TemporaryCVariableAssignment</a> +directives to capture the length of the returned array:</p> +<p>TemporaryCVariableDeclaration glXChooseFBConfig int count; +TemporaryCVariableAssignment glXChooseFBConfig count = _ptr3[0];</p> +<p>The structure of the generated glue code for the return value is +subtly different than in the previous example. The question in this case +is not whether the return value is a pointer to a single object vs. a +pointer to an array of objects; it is what the length of the returned +array is, since we already know that the return type is +pointer-to-pointer and is therefore an array. We use the <a +href="#ReturnValueLength">ReturnValueLength</a> directive for this +case:</p> +<pre><code> ReturnValueLength glXChooseFBConfig count</code></pre> +<p>We add similar Opaque directives to the previous example to yield the +resulting Java bindings for this function:</p> +<pre><code> public static GLXFBConfig[] glXChooseFBConfig(long dpy, int screen, java.nio.IntBuffer attribList, java.nio.IntBuffer nitems); public static GLXFBConfig[] glXChooseFBConfig(long dpy, int screen, int[] attribList, int attribList_offset, - int[] nitems, int nitems_offset); - </pre> - - Note that because the GLXFBConfig data type is returned as an element - of an array, we can not use the Opaque directive to erase this data - type to <code>long</code> as we did with the <code>Display</code> data - type. - - </div> - </div> - <div id="footer"> - <div id="footer_left"> - <span>JogAmp.org</span> - by <a href="http://jogamp.org">http://jogamp.org</a> - is licensed under a <br/> - <a href="http://creativecommons.org/licenses/by/3.0/us/">Creative Commons Attribution 3.0 License</a>. - </div> - </div> - </div> - </body> + int[] nitems, int nitems_offset);</code></pre> +<p>Note that because the GLXFBConfig data type is returned as an element +of an array, we can not use the Opaque directive to erase this data type +to <code>long</code> as we did with the <code>Display</code> data +type.</p> +</body> </html> diff --git a/doc/manual/index.md b/doc/manual/index.md new file mode 100644 index 0000000..760d31b --- /dev/null +++ b/doc/manual/index.md @@ -0,0 +1,1855 @@ +<!--- +We convert markdown using pandoc using `gfm` (GitHub-Flavored Markdown) as source format +and `html5+smart` with a custom template as the target. + +Recipe: +``` + ~/pandoc-buttondown-cgit/pandoc_md2html_local.sh index.md > index.html +``` + +Git repos: +- https://jausoft.com/cgit/users/sgothel/pandoc-buttondown-cgit.git/about/ +- https://github.com/sgothel/pandoc-buttondown-cgit +--> + +<style> +table, th, td { + border: 1px solid black; +} +</style> + +# GlueGen Manual + +*Disclaimer: This documented shall be synchronized with source code, +especially the configuration options.* + +Please also consider reading [GlueGen Native Data & Function +Mapping](../GlueGen_Mapping.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 Native Data & Function Mapping for Java™](../GlueGen_Mapping.html) +- [GlueGen Project Page](https://jogamp.org/gluegen/www/) +- [How To Build](../HowToBuild.html) + +## <span id="Chapter1">Chapter 1 - Introduction</span> + +### <span id="SecIntroduction">Introduction</span> + +GlueGen is a tool which automatically generates the Java and JNI code +necessary to call C libraries. It reads as input 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 is currently powerful enough to bind even low-level +APIs such as the Java Native Interface (JNI) and the AWT Native +Interface (JAWT) back up to the Java programming language. + +GlueGen is currently used to generate the JOGL interface to the OpenGL +3D graphics API and the JOAL interface to the OpenAL audio library. In +the case of JOGL, GlueGen is used not only to bind OpenGL to Java, but +also the low-level windowing system APIs on the Windows, X11 and Mac OS +X platforms. The implementation of the JOGL library is thereby written +in the Java programming language rather than in C, which has offered +considerable advantages during the development of the library. + +GlueGen is designed in modular form and can be extended to alter the +glue code emission style or to generate interface code for other +languages than Java. + +This manual describes how to use GlueGen to bind new C libraries to the +Java programming language. + +### <span id="SecStructure">Structure of the Generated Glue Code</span> + +GlueGen supports two basic styles of glue code generation: everything in +one class, or a separate interface and implementing class. The first +mode, "AllStatic", exposes the underlying C functions as a set of static +Java methods in a concrete class. This is a straightforward binding +mechanism, but has the disadvantage of tying users to a concrete class +(which may or may not be a problem) and makes it more difficult to +support certain kinds of call-through-function-pointer semantics +required by certain C APIs. The second mode, "InterfaceAndImpl", exposes +the C functions as methods in an interface and emits the implementation +of that interface into a separate class and package. The implementing +class is not intended to be in the public API; this more strongly +separates the user from the implementation of the API. Additionally, +because it is necessary to hold an instance of the implementing class in +order to access the underlying C routines, it is easier to support +situations where call-through-function-pointer semantics must be +followed, in particular where those function pointers might change from +instance to instance. + +The generated glue code follows some basic rules in binding C APIs to +Java: + +- C primitive types are exposed as the corresponding Java primitive + type. +- Pointers to typed C primitives (`int*`, `float*`) are bound to + java.nio Buffer subclasses (`IntBuffer`, `FloatBuffer`) and + optionally to Java arrays (`int[]`, `float[]`). + - If a C function takes such a pointer as an outgoing argument, + two method overloadings will generally be produced; one which + accepts a Buffer, and one which accepts a primitive array plus + an integer offset argument. The variant taking a Buffer may + accept either a "direct" NIO Buffer or a non-direct one + (wrapping a Java array). The exception is when such a routine is + specified by the [NioDirectOnly](#NioDirectOnly) directive to + keep a persistent pointer to the passed storage, in which case + only the Buffer variant will be generated, and will only accept + a direct Buffer as argument. + - If a C function returns such a pointer as its result, it will be + exposed as the corresponding Buffer type. In this case it is + also typically necessary to specify to GlueGen via the + [ReturnValueCapacity](#ReturnValueCapacity) directive the number + of addressable elements in the resulting array. +- Pointers to `void*` are bound to java.nio.Buffer. + - By default any C function accepting a `void*` argument will + allow either a direct or non-direct java.nio Buffer to be passed + as argument. If the [NioDirectOnly](#NioDirectOnly) directive is + specified, however, only a direct Buffer will be accepted. + - Similar rules for `void*` return values apply to those for + pointers to typed primitives. +- To avoid an explosion in the number of generated methods, if a + particular API accepts more than one typed primitive pointer + argument, only two overloadings continue to be produced: one + accepting all arrays as arguments and one accepting all Buffers as + arguments. When calling the variant accepting Buffers, all of the + Buffers passed in a particular call must be either direct or + non-direct. Mixing of direct and non-direct Buffers in a given + function call is not supported. +- When a java.nio Buffer is passed from Java to C, the position of the + Buffer is taken into account. The resulting pointer passed to C is + equal to the base address of the Buffer plus the position scaled + appropriately for the size of the primitive elements in the Buffer. + This feature is called "auto-slicing", as it mimics the behavior of + calling Buffer.slice() without the overhead of explicit object + creation. +- Pointers to constant `char*` may be bound to java.lang.String using + the [ArgumentIsString](#ArgumentIsString) or + [ReturnsString](#ReturnsString) directives. +- `#define` statements in header files mapping names to constant + values are exposed as public static final constant values in either + the generated interface or AllStatic class. +- C structs encountered during the glue code generation process and + referenced by the C functions are exposed as Java classes of the + same name (typically the name to which the struct is typedefed). + Each primitive field in the struct is exposed as two methods; a + getter, which accepts no arguments, and a setter, which accepts as + argument a primitive value of the type of the field. Static factory + methods are exposed allowing allocation of these structs from Java + code. The backing storage for these Java classes is a direct + java.nio Buffer. GlueGen fully supports returning of pointers to C + structs up to Java. + +### <span id="SecUnique">Unique Features</span> + +GlueGen contains several unique features making it both a powerful and +easy-to-use tool. + +- C structs are exposed as Java classes. The generated code for these + classes supports both 32-bit and 64-bit platforms. +- C structs containing function pointers are exposed as Java classes + with methods. This makes it easy to interact with low-level C APIs + such as the AWT Native Interface (JAWT) from the Java programming + language level. + - In this context, GlueGen automatically detects which argument to + the various function pointers indicates the "this" pointer, + hiding it at the Java level and passing it automatically. + - GlueGen offers automatic handling of JNI-specific data types + such as `JNIEnv*` and `jobject`. The tool understands that the + `JNIEnv*` argument is implicit and that `jobject` maps to + java.lang.Object at the Java programming language level. While + this is most useful when binding JDK-internal APIs such as the + JAWT to Java, there may be other JNI libraries which expose C + functions taking these data types, and GlueGen can very easily + bind to them. + +### <span id="SecBackground">Background and Design Principles</span> + +This section provides motivation for the design of the GlueGen tool and +is not necessary to understand how to use the tool. + +There are many tools available for assisting in the autogeneration of +foreign function interfaces for various high-level languages. Only a few +examples include +[Header2Scheme](http://alumni.media.mit.edu/~kbrussel/Header2Scheme/), +an early tool allowing binding of a limited subset of C++ to the Scheme +programming language; [SWIG](http://www.swig.org/), a tool released at +roughly the same time as Header2Scheme which by now supports binding C +and C++ libraries to a variety of scripting languages; +[JNIWrapper](http://www.jniwrapper.com/), a commercial tool automating +the binding of C APIs to Java; and +[NoodleGlue](http://web.archive.org/web/20070419183658/http://www.noodleglue.org/noodleglue/noodleglue.html), +a recently-released tool automating the binding of C++ APIs to Java. +Other language-specific tools such as Perl's XS, Boost.Python and many +others exist. + +GlueGen was designed with a few key principles in mind. The most +fundamental was to support binding of the lowest-level APIs on a given +platform up to the Java programming language. The intended goal, in the +context of the JOGL project, was to allow subsets of the Win32 and X11 +APIs to be exposed to Java, and to use those APIs to write the +behind-the-scenes OpenGL context creation and management code in Java +instead of C. This informed several other design goals: + +- Avoid touching the C headers as much as possible. This makes it + easier to upgrade to a more recent version of the C API just by + copying in a new set of headers. +- Avoid touching the generated glue code completely. +- Avoid having to hand-write a lot of generated glue code. Instead, + handle many complex constructs automatically and provide sufficient + control over the glue code generation to avoid having to handwrite + certain native methods where one or two lines of tweaking would + suffice. +- Support all C constructs in the parser and intermediate + representation. The rationale is that it is acceptable to cut + corners in the number of constructs supported in the Java binding, + but not whether the tool can internally represent it in its C type + system. This design goal implies starting with complete a ANSI C + parser coupled with a complete C type system. +- As the tool is targetting the Java programming language, build the + tool in the Java programming language. + +In order to make the problem more tractable, support for binding C++ to +the Java programming language was not considered. C++ adds many +constructs over ANSI C which make it much more difficult to reason about +and to find a useful subset to support binding to Java. Additionally, it +seems that there are relatively few C++-specific libraries in general +use which could be usefully bound to Java, although this may be a matter +of opinion. + +GlueGen was designed with the Java programming language in mind, but is +not necessarily restricted to generating glue code for the Java +language. The tool is divided into separate parse and code generation +phases, and the internal representation is fairly easy to iterate over. +The core driver of GlueGen may therefore be useful in producing other +tools which autogenerate foreign function interfaces to C libraries for +other languages. + +## <span id="Chapter2">Chapter 2 - Using GlueGen</span> + +### <span id="SecAcquiring">Acquiring and Building GlueGen</span> + +The source code for GlueGen may be obtained by cloning the Git +repository: + + $git clone --recursive git://jogamp.org/srv/scm/gluegen.git gluegen + + +To build GlueGen, cd into the gluegen/make folder and invoke ant. + + $ant clean all test + + +Ant 1.8 or later and a Java 6 compatible JDK is required. + +#### <span id="SecCommon">Common Build Problems</span> + +**CharScanner; panic: ClassNotFoundException: com.jogamp.gluegen.cgram.CToken** +This occurs because ANTLR was dropped into the Extensions directory of +the JRE/JDK. On Windows and Linux, delete any ANTLR jars from +jre/lib/ext, and on Mac OS X, delete them from /Library/Java/Extensions. +Use the antlr.jar property in the build.xml to point to a JRE-external +location of this jar file. + +### <span id="SecBasic">Basic Operation</span> + +GlueGen can be run either as an executable jar file +(`java -jar gluegen.jar`; note that +antlr.jar must be in the same directory as gluegen.jar in order for this +invocation to work) or from within Ant as described in the following +section. When run from the command line, GlueGen accepts four kinds of +command-line arguments: + +- -I*dir* (optional) adds *dir* to the include path. Similarly to a C + compiler or preprocessor, GlueGen scans a set of directories to + locate header files it encounters in `#include` directives. Unlike + most C preprocessors, however, GlueGen has no default include path, + so it is typically necessary to supply at least one `-I` option on + the command line in order to handle any `#include` directives in the + file being parsed. +- -E*emitterClassName* (optional) uses *emitterClassName* as the + fully-qualified name of the emitter class which will be used by + GlueGen to generate the glue code. The emitter class must implement + the `com.jogamp.gluegen.GlueEmitter` interface. If this option is + not specified, a `com.jogamp.gluegen.JavaEmitter` will be used by + default. +- -C*cfgFile* adds *cfgFile* to the list of configuration files used + to set up the chosen emitter. This is the means by which a large + number of options are passed in to the GlueGen tool and to the + emitter in particular. Configuration files are discussed more in the + following section. +- \[ filename \| - \] selects the file or standard input from which + GlueGen should read the C header file for which glue code should be + generated. This must be the last command-line argument, and only one + filename argument is supported. To cause multiple header files to be + parsed, write a small .c file \#including the multiple headers and + point GlueGen at the .c file. + +### <span id="SecAnt">Running GlueGen as an Ant Task</span> + +GlueGen can also be invoked as a subtask within Ant. In order to do so, +a path element should be defined as follows: + + <path id="gluegen.classpath"> + <pathelement location="${gluegen.jar}" /> + <pathelement location="${antlr.jar}" /> + </path> + + +where the `gluegen.jar` and `antlr.jar` properties point to the +respective jar files. A taskdef defining the GlueGen task should then be +specified as follows: + + <taskdef name="gluegen" + classname="com.jogamp.gluegen.ant.GlueGenTask" + classpathref="gluegen.classpath" /> + + +At this point GlueGen may be invoked as follows: + + <gluegen src="[header to parse]" + config="[configuration file]" + includeRefid="[dirset for include path]" + emitter="com.jogamp.gluegen.JavaEmitter"> + <classpath refid="gluegen.classpath" /> + </gluegen> + + +Please see the [JOGL](http://jogamp.org/jogl/) and +[JOAL](http://jogamp.org/joal/) build.xml files for concrete, though +non-trivial, examples of how to invoke GlueGen via Ant. + +### <span id="SecJCPP">JCPP</span> + +GlueGen contains and uses the [C preprocessor +JCPP](https://jogamp.org/cgit/jcpp.git/about/), see [original +homepage](https://www.anarres.org/projects/jcpp/). + +Constant values intended for use by end users are defined in many C +libraries' headers using `#define`s rather than constant int +declarations. If the header would be processed by a full C preprocessor, +the `#define` statement's macro name become unavailable for processing +by the glue code generator. Using JCPP allows us to utilize the +`#define` macro names and values. + +JCPP is largely an invisible part of the glue code generation process. +If GlueGen's output is not as expected and there is heavy use of the C +preprocessor in the header, run JCPP against the header directly (JCPP +takes simply the -I and filename arguments accepted by GlueGen) and +examine the output. + +### <span id="SecStub">Stub Headers</span> + +As much as is possible, GlueGen is intended to operate on unmodified C +header files, so that it is easy to upgrade the given C API being bound +to Java simply by dropping in a new set of header files. However, most C +headers contain references to standard headers like `stdio.h`, and if +this header is parsed by GlueGen, the tool will automatically attempt to +generate Java entry points for such routines as `fread` and `fwrite`, +among others. It is impractical to exclude these APIs on a case by case +basis. Therefore, the suggested technique to avoid polluting the binding +with these APIs is to "stub out" the headers. + +GlueGen searches the include path for headers in the order the include +directories were specified to the tool. Placing another directory in +front of the one in which the bulk of the headers are found allows, for +example, an alternative `stdio.h` to be inserted which contains few or +no declarations but which satisfies the need of the dependent header to +find such a file. + +GlueGen uses a complete ANSI and GNU C parser written by John Mitchell +and Monty Zukowski from the set of grammars available for the ANTLR tool +by Terrence Parr. As a complete C parser, this grammar requires all data +types encountered during the parse to be fully defined. Often a +particular header will be included by another one in order to pick up +data type declarations rather than API declarations. Stubbing out the +header with a smaller one providing a "fake" type declaration is a +useful technique for avoiding the binding of unnecessary APIs during the +glue code process. + +Here's an example from the JOGL glue code generation process. The +`glext.h` header defining OpenGL extensions references `stddef.h` in +order to pick up the `ptrdiff_t` data type. We choose to not include the +real stddef.h but instead to swap in a stub header. The contents of this +header are therefore as follows: + + #if defined(_WIN64) + typedef __int64 ptrdiff_t; + #elif defined(__ia64__) || defined(__x86_64__) + typedef long int ptrdiff_t; + #else + typedef int ptrdiff_t; + #endif + + +This causes the ptrdiff_t data type to be defined appropriately for the +current architecture. It will be referenced during the glue code +generation and cause a Java value of the appropriate type (int or long) +to be used to represent it. + +This is not the best example because it involves a data type which +changes size between 32- and 64-bit platforms, and there are otner +considerations to take into account in these situations (see the section +[32- and 64-bit considerations](#Sec32)). Here's another example, again +from the JOGL source tree. JOGL binds the AWT Native Interface, or JAWT, +up to the Java programming language so that the low-level code which +binds OpenGL contexts to Windows device contexts may be written in Java. +The JDK's `jawt_md.h` on the Windows platform includes `windows.h` to +pick up the definitions of data types such as `HWND` (window handle) and +`HDC` (handle to device context). However, it is undesirable to try to +parse the real `windows.h` just to pick up these typedefs; not only does +this header contain thousands of unneeded APIs, but it also uses certain +macro constructs not supported by GlueGen's contained [C +preprocessor](#SecJCPP). To avoid these problems, a "stub" `windows.h` +header is placed in GlueGen's include path containing only the necessary +typedefs: + + typedef struct _handle* HANDLE; + typedef HANDLE HDC; + typedef HANDLE HWND; + + +Note that it is essential that the type being specified to GlueGen is +compatible at least in semantics with the real definition of the HANDLE +typedef in the real `windows.h`, so that during compilation of GlueGen's +autogenerated C code, when the real `windows.h` is referenced by the C +compiler, the autogenerated code will compile correctly. + +This example is not really complete as it also requires [consideration +of the size of data types on 32- and 64-bit platforms](#Sec32) as well +as a discussion of how certain [opaque data types](#SecOpaque) are +described to GlueGen and exposed in its autogenerated APIs. Nonetheless, +it illustrates at a basic level why using a stub header is necessary and +useful in certain situations. + +### <span id="Sec32">32- and 64-bit Considerations</span> + +When binding C functions to the Java programming language, it is +important that the resulting Java code support execution on a 64-bit +platform if the associated native methods are compiled appropriately. In +other words, the public Java API should not change if the underlying C +data types change to another data model such as LP64 (in which longs and +pointers become 64-bit). + +GlueGen internally maintains two descriptions of the underlying C data +model: one for 32-bit architectures and one for 64-bit architectures. +These machine descriptions are used when deciding the mapping between +integral C types such as int and long and the corresponding Java types, +as well as when laying out C structs for access by the Java language. +For each autogenerated C struct accessor, both a 32-bit and 64-bit +variant are generated behind the scenes, ensuring that the resulting +Java code will run correctly on both 32-bit and 64-bit architectures. + +When generating the main class containing the bulk of the method +bindings, GlueGen uses the 64-bit machine description to map C data +types to Java data types. This ensures that the resulting code will run +properly on 64-bit platforms. Note that it also generally means that C +`long`s will be mapped to Java `long`s, since an LP64 data model is +assumed. + +If [Opaque directives](#SecOpaque) are used to cause a given C integer +or pointer data type to be mapped directly to a Java primitive type, +care should be taken to make sure that the Java primitive type is wide +enough to hold all of the data even on 64-bit platforms. Even if the +data type is defined in the header file as being only a 32-bit C +integer, if there is a chance that on a 64-bit platform the same header +may define the data type as a 64-bit C integer or long, the Opaque +directive should map the C type to a Java long. + +### <span id="SecOpaque">Opaque Directives</span> + +Complex header files may contain declarations for certain data types +that are either too complex for GlueGen to handle or unnecessarily +complex from the standpoint of glue code generation. In these situations +a stub header may be used to declare a suitably compatible typedef for +the data type. An [Opaque](#Opaque) directive can be used to map the +resulting typedef to a Java primitive type if it is undesirable to +expose it as a full-blown Java wrapper class. + +GlueGen hashes all typedefs internally down to their underlying +primitive type. (This is probably not really correct according to the C +type system, but is correct enough from a glue code generation +standpoint, where if the types are compatible they are considered +equivalent.) This means that if the parser encounters + + typedef void* LPVOID; + + +then an Opaque directive stating + + Opaque long LPVOID + + +will cause all `void*` or `LPVOID` arguments in the API to be mapped to +Java longs, which is almost never desirable. Unfortunately, it is not +currently possible to distinguish between the LPVOID typedef and the +underlying `void*` data type in this situation. + +A similar problem occurs for other data types for which Opaque +directives may be desired. For example, a Windows HANDLE equates to a +typedef to `void*`, but performing this typedef in a stub header and +then adding the Opaque directive + + Opaque long HANDLE + + +will cause all void\* arguments to be exposed as Java longs instead of +Buffers, which is again undesirable. Attempting to work around the +problem by typedef'ing HANDLE to an integral type, as in: + + typedef long HANDLE; + + +may itself have problems, because GlueGen will assume the two integral +types are compatible and not perform any intermediate casts between +HANDLE and jlong in the autogenerated C code. (When casting between a +pointer type and a JNI integral type such as jlong in C code, GlueGen +automatically inserts casts to convert the pointer first to an +"intptr_t" and then to the appropriate JNI type, in order to silence +compiler warnings and/or errors.) + +What is desired is to produce a new type name distinct from all others +but still compatible with the pointer semantics of the original type. +Then an Opaque directive can be used to map the new type name to, for +example, a Java long. + +To implement this in the context of the HANDLE example, the following +typedef may be inserted into the stub header: + + typedef struct _handle* HANDLE; + + +This uses a pointer to an anonymous struct name to produce a new pointer +type. This is legal ANSI C and is supported by GlueGen's parser without +having seen a declaration for "struct \_handle". Subsequently, an Opaque +directive can be used to map the HANDLE data type to a Java long: + + Opaque long HANDLE + + +Now HANDLEs are exposed to Java as longs as desired. A similar technique +is used to expose XIDs on the X11 platform as Java longs. + +### <span id="SecSubstitution">Argument Name Substitution</span> + +Certain configuration file directives allow the insertion of Java or C +code at various places in the generated glue code, to both eliminate the +need to hand-edit the generated glue code as well as to minimize the +hand-writing of glue code, which sidesteps the GlueGen process. In some +situations the inserted code may reference incoming arguments to compute +some value or perform some operation. Examples of directives supporting +this substitution include [ReturnValueCapacity](#ReturnValueCapacity) +and [ReturnedArrayLength](#ReturnedArrayLength). + +The expressions in these directives may contain Java MessageFormat +expressions like `{0}` which refer to the incoming argument names to the +function. `{0}` refers to the first incoming argument. + +Strongly-typed C primitive pointers such as `int*`, which ordinarily +expand to overloaded Java methods taking e.g. `int[]` as well as +`IntBuffer`, present a problem. The expansion to `int[] arr` also +generates an `int arr_offset` argument to be able to pass a pointer into +the middle of the array down to C. To allow the same MessageFormat +expression to be used for both cases, the subsitution that occurs when +such a primitive array is referenced is the string +`arr, arr_offset`; in other words, the +subtituted string contains a comma. This construct may be used in the +following way: the code being manually inserted may itself contain a +method call taking e.g. `{3}` (the incoming argument index of the +primitive array or buffer). The user should supply two overloaded +versions of this method, one taking a strongly-typed Buffer and one +taking e.g. an `int[] arr` and `int arr_offset` argument. The +implementation of `RangeCheck`s for primitive arrays and strongly-typed +buffers uses this construct. + +It should be noted that in the autogenerated C code the offset argument +is expressed in bytes while at the Java level it is expressed in +elements. Most uses of GlueGen will probably not have to refer to the +primitive array arguments in C code so this slight confusion should be +minor. + +### <span id="SecConfiguration">Configuration File Directives</span> + +In addition to the C headers, GlueGen requires a certain amount of +metadata in the form of configuration files in order to produce its glue +code. There are three basic reasons for this: first, GlueGen must be +informed into which Java classes the C methods are to be bound; second, +there are many configuration options for the generated glue code, and +passing them all on the command line is infeasible; and third, there are +ambiguities in many constructs in the C programming language which must +be resolved before a Java binding can be produced. + +The contents of the configuration file are dependent on the class of +emitter specified to GlueGen. Currently there are three built-in emitter +classes: JavaEmitter, which produces a basic, static Java binding of C +functions; ProcAddressEmitter, which extends JavaEmitter by calling the +underlying C functions through function pointers, resulting in more +dynamic behavior and supporting C APIs with optional functionality; and +GLEmitter, which specializes ProcAddressEmitter to support some +OpenGL-specific constructs. The GLEmitter will be ignored in this manual +as it is specialized for JOGL and provides very little additional +functionality beyond the ProcAddressEmitter. The JavaEmitter and +ProcAddressEmitter support many options in their configuration files. As +the ProcAddressEmitter is a subclass of JavaEmitter, all of the +constructs in the JavaEmitter's configuration files are also legal in +the ProcAddressEmitter's configuration files. + +The configuration files have a very simple line-by-line structure, and +are parsed by a very rudimentary, hand-written parser. Each +non-whitespace and non-comment line (note: comment lines begin with '#') +contains a directive like `Package`, `Style` or `JavaClass` followed by +arguments to that directive. There are a certain set of directives that +are required for any code generation; others are optional and their +omission results in some default behavior. Directives are +case-insensitive. + +The following is an exhaustive list of the options currently supported +by each of these emitters' configuration files. It is difficult to see +exactly how to use the tool based simply on these descriptions, so the +[examples](#Chapter3) may be more helpful in seeing exactly how to +structure a configuration file for proper glue code generation. + +#### <span id="SecJavaEmitter">JavaEmitter Configuration</span> + +Note that only a very few of the following directives are specified as +being "required" rather than "optional"; these indicate the minimal +directives needed for a valid configuration file to begin to get glue +code to be produced. In general, these are [Package](#Package), +[ImplPackage](#ImplPackage), [JavaClass](#JavaClass), +[ImplJavaClass](#ImplJavaClass), and [Style](#Style). Other directives +such as [NioDirectOnly](#NioDirectOnly) are required in some +circumstances for the glue code to be correct, and some such as +[ReturnedArrayLength](#ReturnedArrayLength), +[ReturnValueCapacity](#ReturnValueCapacity), and +[ReturnValueLength](#ReturnValueLength) should be specified in some +situations in order for certain return values to be useful at the Java +level. + +The following directives are specified in alphabetical order, although +this is not necessarily the best semantic order. + +**<span id="AccessControl">AccessControl</span>** +Syntax: +`AccessControl [method name] [ PUBLIC | PROTECTED | PRIVATE | PACKAGE_PRIVATE ]` +(optional) Controls the access control of a certain Java method +corresponding to a C function. The access control of all APIs defaults +to public. This is useful when using the C binding of a particular +function only as one implementation strategy of the real public API and +using [CustomJavaCode](#CustomJavaCode) to write the exposed API. In +this case is most useful in conjunction with +[RenameJavaMethod](#RenameJavaMethod). + +**<span id="ArgumentIsString">ArgumentIsString</span>** +Syntax: +`ArgumentIsString [function name] [indices...]` +where the first argument index is 0 +(optional) For a C function with one or more outgoing `char*` (or +compatible data type) arguments, indicates that those arguments are +semantically null-terminated C strings rather than arbitrary arrays of +bytes. The generated glue code will be modified to emit those arguments +as java.lang.String objects rather than `byte[]` or `ByteBuffer`. + +**<span id="ArgumentIsPascalString">ArgumentIsPascalString</span>** +Syntax: +`ArgumentIsPascalString [function name] [indice-tuples...]`, +with each tuple being the argument-index for the '`int length`' and the +'`char* value`' argument with index 0 for the the first argument +(optional) For a C function with one or more outgoing '`int length`' and +'`char* value`' (or compatible data type) arguments, indicates that +those arguments are semantically non-null-terminated Pascal strings +rather than null-terminated C strings or arbitrary arrays of bytes. The +generated glue code will be modified to emit those arguments as +java.lang.String objects rather than `byte[]` or `ByteBuffer`. + +**<span id="ClassJavadoc">ClassJavadoc</span>** +Syntax: `ClassJavadoc [class name] [code...]` +(optional) Causes the specified line of code to be emitted in the +appropriate place in the generated code to become the per-class Javadoc +for the specified class. By default GlueGen produces no Javadoc for its +generated classes, so this is the mechanism by which a user can emit +Javadoc for these classes. The specified Javadoc undergoes no +transformation by GlueGen, so the initial `/**` and trailing `*/` must +be included in the correct place. Each line of Javadoc is emitted in the +order encountered during parsing of the configuration files. + +**<span id="CustomCCode">CustomCCode</span>** +Syntax: `CustomCCode [code...]` +(optional) Causes the specified line of C code to be emitted into the +generated native code for the implementing class. Currently there is no +way (and no real need) to be able to emit custom C code into any other +generated .c file, so the class name in the +[CustomJavaCode](#CustomJavaCode) directive is omitted. + +**<span id="CustomJavaCode">CustomJavaCode</span>** +Syntax: `CustomJavaCode [class name] [code...]` +(optional) Causes the specified line of Java code to be emitted into the +specified generated Java class. Can be used to emit code into any +generated class: the public interface, the implementing class, the sole +concrete class (in the case of the AllStatic [Style](#Style)), or any of +the Java classes corresponding to referenced C structs in the parsed +headers. This usage is somewhat verbose, and the [IncludeAs](#IncludeAs) +directive provides a more concise way of including large bodies of Java +code into the generated code. + +**<span id="CustomJNICode">CustomJNICode</span>** +Syntax: `CustomJNICode [class name] [code...]` +(optional) Causes the specified line of C code to be emitted into the +generated JNI code related of specified Java class. Can be used to emit +JNI code related of any generated class: the public interface, the +implementing class, the sole concrete class (in the case of the +AllStatic [Style](#Style)), or any of the Java classes corresponding to +referenced C structs in the parsed headers. This usage is somewhat +verbose, and the [IncludeAs](#IncludeAs) directive provides a more +concise way of including large bodies of C code into the generated code. + +**<span id="EmitStruct">EmitStruct</span>** +Syntax: `EmitStruct [C struct type name]` +(optional) Forces a Java class to be emitted for the specified C struct. +Normally only those structs referenced directly by the parsed C APIs +have corresponding Java classes emitted. + +**<span id="GlueGenRuntimePackage">GlueGenRuntimePackage</span>** +Syntax: +`GlueGenRuntimePackage [package name, like com.jogamp.gluegen.runtime]` +(optional) Changes the package in which the generated glue code expects +to find its run-time helper classes (like Buffers, CPU, StructAccessor). +Defaults to `com.jogamp.gluegen.runtime` (no quotes). This is useful if +you want to bundle the runtime classes in your application without the +possibility of interfering with other versions elsewhere in the system. + +**<span id="ExtendedInterfaceSymbolsIgnore">ExtendedInterfaceSymbolsIgnore</span>** +Syntax: `ExtendedInterfaceSymbolsIgnore [Java file]` +(optional) Causes all autogenerated Java interface ignore all symbols +from interface declared inside named Java source file. +This directive can be used with [Extends](#Extends) directive. +Cf here for more information : +[GlueGen_Mapping](../GlueGen_Mapping.html#oo-style-example) + +**<span id="ExtendedInterfaceSymbolsOnly">ExtendedInterfaceSymbolsOnly</span>** +Syntax: `ExtendedInterfaceSymbolsOnly [Java file]` +(optional) Causes all autogenerated Java interface generate only symbols +from interface declared inside named Java source file. +This directive can be used with [Extends](#Extends) directive. +Cf here for more information : +[GlueGen_Mapping](../GlueGen_Mapping.html#oo-style-example) + +**<span id="ExtendedImplementationSymbolsIgnore">ExtendedImplementationSymbolsIgnore</span>** +Syntax: `ExtendedImplementationSymbolsIgnore [Java file]` +(optional) Causes all autogenerated Java classes ignore all symbols from +interface or classe declared inside named Java source file. +This directive can be used with [ParentClass](#ParentClass) directive. +Cf here for more information : +[GlueGen_Mapping](../GlueGen_Mapping.html#oo-style-example) + +**<span id="ExtendedImplementationSymbolsOnly">ExtendedImplementationSymbolsOnly</span>** +Syntax: `ExtendedImplementationSymbolsOnly [Java file]` +(optional) Causes all autogenerated Java classes generate only symbols +from interface or classe declared inside named Java source file. +This directive can be used with [ParentClass](#ParentClass) directive. +Cf here for more information : +[GlueGen_Mapping](../GlueGen_Mapping.html#oo-style-example) + +**<span id="ExtendedIntfAndImplSymbolsIgnore">ExtendedIntfAndImplSymbolsIgnore</span>** +Syntax: `ExtendedIntfAndImplSymbolsIgnore [Java file]` +(optional) Causes all autogenerated Java interface and classes ignore +all symbols from interface or classe declared inside named Java source +file. +This directive can be used with [Extends](#Extends) or +[ParentClass](#ParentClass) directives. +Cf here for more information : +[GlueGen_Mapping](../GlueGen_Mapping.html#oo-style-example) + +**<span id="ExtendedIntfAndImplSymbolsOnly">ExtendedIntfAndImplSymbolsOnly</span>** +Syntax: `ExtendedIntfAndImplSymbolsOnly [Java file]` +(optional) Causes all autogenerated Java interface and classes generate +only symbols from interface or classe declared inside named Java source +file. +This directive can be used with [Extends](#Extends) or +[ParentClass](#ParentClass) directives. +Cf here for more information : +[GlueGen_Mapping](../GlueGen_Mapping.html#oo-style-example) + +**<span id="Extends">Extends</span>** +Syntax: `Extends [Java interface name] [interface name to extend] ` +(optional) Causes the specified autogenerated Java interface to declare +that it extends another one. This directive may only be applied to +autogenerated interfaces, not concrete classes. For concrete classes, +use [Implements](#Implements) directive or [ParentClass](#ParentClass) +directive. + +**<span id="HierarchicalNativeOutput">HierarchicalNativeOutput</span>** +Syntax: `HierarchicalNativeOutput true` +(optional) If "true", makes subdirectories for the generated native code +matching the package names of the associated classes. This is typically +not needed (or desired, as it complicates the compilation process for +this native code) and defaults to false. + +**<span id="Ignore">Ignore</span>** +Syntax: `Ignore [regexp]` +(optional) Ignores one or more functions or data types matching the +regexp argument which are encountered during parsing of the C headers. +By default GlueGen will emit all encountered C functions as well as Java +classes corresponding to all C structs referenced by those functions. +Related directives are [IgnoreNot](#IgnoreNot), [Unignore](#Unignore) +and [EmitStruct](#EmitStruct). + +**<span id="IgnoreField">IgnoreField</span>** +Syntax: `IgnoreField [struct type name] [field name]` +(optional) Causes the specified field of the specified struct type to be +ignored during code generation, typically because it is too complex for +GlueGen to handle. + +**<span id="IgnoreNot">IgnoreNot</span>** +Syntax: see [Ignore](#Ignore). (optional) Similar to the +[Ignore](#Ignore) directive, but evaluates the negation of the passed +regexp when deciding whether to ignore the given function or data type. +The [Unignore](#Unignore) mechanism may be used with IgnoreNot as well. +NOTE: the IgnoreNot mechanism may ultimately turn out to be superfluous; +the authors do not have sufficient experience with regular expressions +to know whether general negation of a regexp is possible. Feedback in +this area would be appreciated. + +**<span id="Implements">Implements</span>** +Syntax: +`Implements [Java class name] [interface name to implement]` +(optional) Causes the specified autogenerated Java concrete class to +declare that it implements the specified interface. This directive may +only be applied to autogenerated concrete classes, not interfaces. For +interfaces, use the [Extends](#Extends) directive. + +**<span id="ImplJavaClass">ImplJavaClass</span>** +Syntax: `ImplJavaClass [class name]` +(optional) Specifies the name of the typically non-public, +implementation Java class which contains the concrete Java and native +methods for the glue code. If the emission style is AllStatic, there is +no distinction between the public and implementation class and +ImplJavaClass should not be specified. Otherwise, if the ImplJavaClass +is unspecified, it defaults to the JavaClass name plus "Impl". (If both +are unspecified in this configuration, an error is reported.) See also +[JavaClass](#JavaClass). + +**<span id="ImplPackage">ImplPackage</span>** +Syntax: `ImplPackage [package name]` +(optional) Specifies the package name into which the implementing class +containing the concrete Java and native methods will be emitted, +assuming an emission style of InterfaceAndImpl or ImplOnly. If +AllStatic, there is no separate implementing class from the public +interface. If the emission style is not AllStatic and the ImplPackage is +not specified, it defaults to the Package plus ".impl". See also +[Package](#Package). + +**<span id="Import">Import</span>** +Syntax: `Import [package name]` (no trailing semicolon) +(optional) Adds an import statement at the top of each generated Java +source file. + +**<span id="Include">Include</span>** +Syntax: `Include [filename]` +(optional) Causes another configuration file to be read at the current +point in parsing the current configuration file. The filename argument +may be either absolute or relative; in the latter case it is specified +relative to the location of the current configuration file. + +**<span id="IncludeAs">IncludeAs</span>** +Syntax: `IncludeAs [prefix tokens] [filename]` +(optional) Similar to the [Include](#Include) directive, but prepends +the specified prefix tokens on to every line of the file to be read. The +last token parsed is the name of the file to be read. This allows, for +example, [CustomJavaCode](#CustomJavaCode) to be stored as Java source +rather than in the configuration file; in this example the configuration +file might contain +`IncludeAs CustomJavaCode MyClass MyClass-CustomJavaCode.java`. + +**<span id="JavaClass">JavaClass</span>** +Syntax: `JavaClass [class name]` +(optional / required) Specifies the name of the public, +non-implementation Java class or interface into which the glue code will +be generated. If the emission style is not ImplOnly, the JavaClass +directive is required. See also [ImplJavaClass](#ImplJavaClass). + +**<span id="JavaEpilogue">JavaEpilogue</span>** +Syntax: `JavaEpilogue [C function name] [code...]` +(optional) Adds the specified code as an epilogue in the Java method for +the specified C function; this code is run after the underlying C +function has been called via the native method but before any result is +returned. As in the [ReturnedArrayLength](#ReturnedArrayLength) and +other directives, [argument name substitution](#SecSubstitution) is +performed on MessageFormat expressions in the specified code. See also +[JavaPrologue](#JavaPrologue). + +**<span id="JavaOutputDir">JavaOutputDir</span>** +Syntax: `JavaOutputDir [directory name]` +(optional) Specifies the root directory into which the emitted Java code +will be produced. Subdirectories for the packages of the associated Java +classes will be automatically created. If unspecified, defaults to the +current working directory. + +**<span id="JavaPrologue">JavaPrologue</span>** +Syntax: `JavaPrologue [C function name] [code...]` +(optional) Adds the specified code as a prologue in the Java method for +the specified C function; this code is run before the underlying C +function is called via the native method. As in the +[ReturnedArrayLength](#ReturnedArrayLength) and other directives, +[argument name substitution](#SecSubstitution) is performed on +MessageFormat expressions in the specified code. See also +[JavaEpilogue](#JavaEpilogue). + +**<span id="ManuallyImplement">ManuallyImplement</span>** +Syntax: `ManuallyImplement [function name]` +(optional) Indicates to GlueGen to not produce a method into the +implementing class for the specified C function; the user must provide +one via the [CustomJavaCode](#CustomJavaCode) directive. If the emission +style is InterfaceAndImpl or InterfaceOnly, a public method will still +be generated for the specified function. + +**<span id="MaxOneElement">MaxOneElement</span>** +Syntax: `MaxOneElement [function name]` +(optional) Indicates that the specified C function/attribute which +returns a single element instead a ByteBuffer if signature or compatible +type actually returns a pointer like int\* but isn't an array. +Cf here for more information : +[GlueGen_Mapping](../GlueGen_Mapping.html#gluegen-struct-settings) + +**<span id="NativeOutputDir">NativeOutputDir</span>** +Syntax: `NativeOutputDir [directory name]` +(optional) Specifies the root directory into which the emitted JNI code +will be produced. If unspecified, defaults to the current working +directory. See also +[HierarchicalNativeOutput](#HierarchicalNativeOutput). + +**<span id="NioDirectOnly">NioDirectOnly</span>** +Syntax: `NioDirectOnly [function name]` +(required when necessary) When passing a pointer down to a C API, it is +semantically undefined whether the underlying C code expects to treat +that pointer as a persistent pointer, living past the point of return of +the function call, or whether the pointer is used only during the +duration of the function call. For APIs taking C primitive pointers such +as `void*`, `float*`, etc., GlueGen will typically generate up to two +overloaded Java methods, one taking a `Buffer` or `Buffer` subclass such +as `FloatBuffer`, and one taking a primitive array such as `float[]`. +(In the case of `void*` outgoing arguments, GlueGen produces only one +variant taking a Buffer.) Normally the generated glue code accepts +either a "direct" or non-"direct" buffer (according to the New I/O APIs) +as argument. However, if the semantics of the C function are that it +either expects to hold on to this pointer past the point of the function +call, or if it can block while holding on to the pointer, the +`NioDirectOnly` directive **must** be specified for this C function in +order for the generated glue code to be correct. Failing to observe this +requirement may cause JVM hangs or crashes. + +**<span id="Opaque">Opaque</span>** +Syntax: +`Opaque [Java primitive data type] [C data type]` +(optional) Causes a particular C data type to be exposed in opaque form +as a Java primitive type. This is most useful for certain pointer types +for which it is not desired to generate full Java classes but instead +expose them to Java as e.g. `long`s. It is also useful for forcing +certain integral C data types to be exposed as e.g. `long` to Java to +ensure 64-bit cleanliness of the generated glue code. See the +[examples](#Chapter3). The C data type may be a multiple-level pointer +type; for example `Opaque long void**`. Note that it is not currently +supported to make a given data type opaque for just a few functions; the +Opaque directive currently applies to all C functions in the headers +being parsed. This means that sweeping Opaque declarations like +`Opaque long void*` will likely have unforseen and undesirable +consequences. + +**<span id="Package">Package</span>** +Syntax: `Package [package name]` (no trailing semicolon) +(optional / required) Specifies the package into which the public +interface or class for the autogenerated glue code will be generated. +Required whenever the emission style is not ImplOnly. See also +[ImplPackage](#ImplPackage). + +**<span id="ParentClass">ParentClass</span>** +Syntax: `ParentClass [Java class name] [class name to extend] ` +(optional) Causes the specified autogenerated Java classe to declare +that it extends another one. This directive may only be applied to +autogenerated classes, not interface. For interfaces, use the +[Extends](#Extends) directive. + +**<span id="RangeCheck">RangeCheck</span>** +Syntax: `RangeCheck [C function name] [argument number] [expression]` +(optional) Causes a range check to be performed on the specified array +or Buffer argument of the specified autogenerated Java method. This +range check ensures, for example, that a certain number of elements are +remaining in the passed Buffer, knowing that the underlying C API will +access no more than that number of elements. For range checks that +should be expressed in terms of a number of bytes rather than a number +of elements, see the [RangeCheckBytes](#RangeCheckBytes) directive. As +in the [ReturnedArrayLength](#ReturnedArrayLength) and other directives, +[argument name substitution](#SecSubstitution) is performed on +MessageFormat expressions. + +**<span id="RangeCheckBytes">RangeCheckBytes</span>** +Syntax: +`RangeCheckBytes [C function name] [argument number] [expression]` +(optional) Same as the [RangeCheck](#RangeCheck) directive, but the +specified expression is treated as a minimum number of bytes remaining +rather than a minimum number of elements remaining. This directive may +not be used with primitive arrays. + +**<span id="RenameJavaMethod">RenameJavaMethod</span>** +Syntax: `RenameJavaMethod [from name] [to name]` +(optional) Causes the specified C function to be emitted under a +different name in the Java binding. This is most useful in conjunction +with the [AccessControl](#AccessControl) directive when the C function +being bound to Java is only one potential implementation of the public +API, or when a considerable amount of Java-side custom code is desired +to wrap the underlying C native method entry point. + +**<span id="RenameJavaType">RenameJavaType</span>** +Syntax: `RenameJavaType [from name] [to name]` +(optional) Causes the specified C struct to be exposed as a Java class +under a different name. This only applies to autogenerated classes +corresponding to C structs encountered during glue code generation; full +control is provided over the name of the top-level classes associated +with the set of C functions via the [JavaClass](#JavaClass) and +[ImplJavaClass](#ImplJavaClass) directives. + +**<span id="ReturnedArrayLength">ReturnedArrayLength</span>** +Syntax: +`ReturnedArrayLength [C function name] [expression]` +where `expression` is a legal Java expression with MessageFormat +specifiers such as "{0}". These specifiers will be replaced in the +generated glue code with the incoming argument names where the first +argument to the method is numbered 0. See the section on [argument name +substitution](#SecSubstitution). +(optional) For a function returning a compound C pointer type such as an +`XVisualInfo*`, indicates that the returned pointer is to be treated as +an array and specifies the length of the returned array as a function of +the arguments passed to the function. Note that this directive differs +subtly from [ReturnValueCapacity](#ReturnValueCapacity) and +ReturnValueLength. It is also sometimes most useful in conjunction with +the [TemporaryCVariableDeclaration](#TemporaryCVariableDeclaration) and +TemporaryCVariableAssignment directives. + +**<span id="ReturnsString">ReturnsString</span>** +Syntax: `ReturnsString [function name]` +(optional) Indicates that the specified C function which returns a +`char*` or compatible type actually returns a null-terminated C string +which should be exposed as a java.lang.String. NOTE: currently does not +properly handle the case where this storage needs to be freed by the end +user. In these situations the data should be returned as a direct +ByteBuffer, the ByteBuffer converted to a String using custom Java code, +and the ByteBuffer freed manually using another function bound to Java. + +**<span id="ReturnsStringOnly">ReturnsStringOnly</span>** +Syntax: `ReturnsStringOnly [function name]` +(optional) Like the [ReturnsString](#ReturnsString) instruction, but +without the classic getters and setters with ByteBuffer. +Cf here for more information : +[GlueGen_Mapping](../GlueGen_Mapping.html#gluegen-struct-settings) + +**<span id="ReturnValueCapacity">ReturnValueCapacity</span>** +Syntax: +`ReturnValueCapacity [C function name] [expression]` +(optional) Specifies the capacity of a java.nio `Buffer` or subclass +wrapping a C primitive pointer such as `char*` or `float*` being +returned from a C function. Typically necessary in order to properly use +such pointer return results from Java. As in the +[ReturnedArrayLength](#ReturnedArrayLength) directive, [argument name +substitution](#SecSubstitution) is performed on MessageFormat +expressions. + +**<span id="ReturnValueLength">ReturnValueLength</span>** +Syntax: `ReturnValueLength [C function name] [expression]` +(optional) Specifies the length of a returned array of pointers, +typically to C structs, from a C function. This differs from the +[ReturnedArrayLength](#ReturnedArrayLength) directive in the pointer +indirection to the array elements. The +[ReturnedArrayLength](#ReturnedArrayLength) directive handles slicing up +of a linear array of structs, while the ReturnValueLength directive +handles boxing of individual elements of the array (which are pointers) +in to the Java class which wraps that C struct type. See the +[examples](#Chapter3) for a concrete example of usage. As in the +[ReturnedArrayLength](#ReturnedArrayLength) directive, [argument name +substitution](#SecSubstitution) is performed on MessageFormat +expressions. + +**<span id="RuntimeExceptionType">RuntimeExceptionType</span>** +Syntax: `RuntimeExceptionType [class name]` +(optional) Specifies the class name of the exception type which should +be thrown when run-time related exceptions occur in the generated glue +code, for example if a non-direct Buffer is passed to a method for which +[NioDirectOnly](#NioDirectOnly) was specified. Defaults to +`RuntimeException`. + +**<span id="StructPackage">StructPackage</span>** +Syntax: +`StructPackage [C struct type name] [package name]`. +Package name contains no trailing semicolon. +(optional) Indicates that the specified Java class corresponding to the +specified C struct should be placed in the specified package. By +default, these autogenerated Java classes corresponding to C structs are +placed in the main package (that defined by +[PackageName](#PackageName)). + +**<span id="Style">Style</span>** +Syntax: +` Style [ AllStatic | InterfaceAndImpl |InterfaceOnly | ImplOnly ] ` +(optional) Defines how the Java API for the parsed C headers is +structured. If AllStatic, one concrete Java class will be generated +containing static methods corresponding to the C entry points. If +InterfaceAndImpl, a public Java interface will be generated into the +[Package](#Package) with non-static methods corresponding to the C +functions, and an "implementation" concrete Java class implementing this +interface will be generated into the [ImplPackage](#ImplPackage). If +InterfaceOnly, the InterfaceAndImpl code generation style will be +followed, but only the interface will be generated. If ImplOnly, the +InterfaceAndImpl code generation style will be followed, but only the +concrete implementing class will be generated. The latter two options +are useful when generating a public API in which certain operations are +unimplemented on certain platforms; platform-specific implementation +classes can be generated which implement or leave unimplemented various +parts of the API. + +**<span id="TemporaryCVariableAssignment">TemporaryCVariableAssignment</span>** +Syntax: `TemporaryCVariableAssignment [C function name][code...]` +(optional) Inserts a C variable assignment declared using the +[TemporaryCVariableDeclaration](#TemporaryCVariableDeclaration) +directive in to the body of a particular autogenerated native method. +The assignment is performed immediately after the call to the underlying +C function completes. This is typically used in conjunction with the +[ReturnValueCapacity](#ReturnValueCapacity) or +[ReturnValueLength](#ReturnValueLength) directives to capture the size +of a returned C buffer or array of pointers. See the +[examples](#Chapter3) for a concrete example of usage of this directive. +Note that unlike, for example, the +[ReturnedArrayLength](#ReturnedArrayLength) directive, no substitution +is performed on the supplied code, so the user must typically have +previously looked at the generated code and seen what work needed to be +done and variables needed to be examined at exactly that line. + +**<span id="TemporaryCVariableDeclaration">TemporaryCVariableDeclaration</span>** +Syntax: +`TemporaryCVariableDeclaration [C function name] [code...]` +(optional) Inserts a C variable declaration in to the body of a +particular autogenerated native method. This is typically used in +conjunction with the +[TemporaryCVariableAssignment](#TemporaryCVariableAssignment) and +[ReturnValueCapacity](#ReturnValueCapacity) or +[ReturnValueLength](#ReturnValueLength) directives to capture the size +of a returned C buffer or array of pointers. See the +[examples](#Chapter3) for a concrete example of usage of this directive. + +**<span id="Unignore">Unignore</span>** +Syntax: `Unignore [regexp]` +(optional) Removes a previously-defined [Ignore](#Ignore) directive. +This is useful when one configuration file includes another and wishes +to disable some of the Ignores previously specified. + +**<span id="Unimplemented">Unimplemented</span>** +Syntax: `Unimplemented [regexp]` +(optional) Causes the binding for the functions matching the passed +regexp to have bodies generated which throw the stated +[RuntimeExceptionType](#RuntimeExceptionType) indicating that this +function is unimplemented. This is most useful when an API contains +certain functions that are not supported on all platforms and there are +multiple implementing classes being generated, one per platform. + +#### <span id="SecProcAddressEmitter">ProcAddressEmitter Configuration</span> + +The ProcAddressEmitter is a subclass of the core JavaEmitter which knows +how to call C functions through function pointers. In particular, the +ProcAddressEmitter detects certain constructs in C header files which +imply that the APIs are intended to be called through function pointers, +and generates the glue code appropriately to support that. + +The ProcAddressEmitter detects pairs of functions and function pointer +typedefs in a set of header files. If it finds a matching pair, it +converts the glue code emission style for that API to look for the +function to call in an autogenerated table called a ProcAddressTable +rather than linking the autogenerated JNI code directly to the function. +It then changes the calling convention of the underlying native method +to pass the function pointer from Java down to C, where the +call-through-function-pointer is performed. + +The ProcAddressEmitter discovers the function and function pointer pairs +by being informed of the mapping between their names by the user. In the +OpenGL and OpenAL libraries, there are fairly simple mappings between +the functions and function pointers. For example, in the OpenGL +`glext.h` header file, one may find the following pair: + + GLAPI void APIENTRY glFogCoordf (GLfloat); + ... + typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord); + + +Therefore the mapping rule between the function name and the function +pointer typedef for the OpenGL extension header file is "PFN + +Uppercase(funcname) + PROC". Similarly, in the OpenAL 1.1 header files, +one may find the following pair: + + AL_API void AL_APIENTRY alEnable( ALenum capability ); + ... + typedef void (AL_APIENTRY *LPALENABLE)( ALenum capability ); + + +Therefore the mapping rule between the function name and the function +pointer typedef for the OpenAL header files is "LP + +Uppercase(funcname)". + +These are the two principal function pointer-based APIs toward which the +GlueGen tool has currently been applied. It may turn out to be that this +simple mapping heuristic is insufficient, in which case it will need to +be extended in a future version of the GlueGen tool. + +Note that it is currently the case that in order for the +ProcAddressEmitter to notice that a given function should be called +through a function pointer, it must see both the function prototype as +well as the function pointer typedef. Some headers, in particular the +OpenAL headers, have their `#ifdefs` structured in such a way that +either the declaration or the typedef is visible, but not both +simultaneously. Because the [JCPP](#SecJCPP) C preprocessor GlueGen uses +obeys `#ifdefs`, it is in a situation like this that the headers would +have to be modified to allow GlueGen to see both declarations. + +The following directives are specified in alphabetical order, although +this is not necessarily the best semantic order. The ProcAddressEmitter +also accepts all of the directives supported by the JavaEmitter. The +required directives are +[GetProcAddressTableExpr](#GetProcAddressTableExpr) and +[ProcAddressNameExpr](#ProcAddressNameExpr). + +**<span id="EmitProcAddressTable">EmitProcAddressTable</span>** +Syntax: `EmitProcAddressTable [true | false]` +(optional) Indicates whether to emit the ProcAddressTable during glue +code generation. Defaults to false. + +**<span id="ForceProcAddressGen">ForceProcAddressGen</span>** +Syntax: `ForceProcAddressGen [function name]` +(optional) Indicates that a ProcAddressTable entry should be produced +for the specified function even though it does not have an associated +function pointer typedef in the header. This directive does not +currently cause the autogenerated Java and C code to change to +call-through-function-pointer style, which should probably be considered +a bug. (FIXME) + +**<span id="GetProcAddressTableExpr">GetProcAddressTableExpr</span>** +Syntax: `GetProcAddressTableExpr [expression]` +(required) Defines the Java code snippet used by the generated glue code +to fetch the ProcAddressTable containing the function pointers for the +current API. It is up to the user to decide where to store the +ProcAddressTable. Common places for it include in an instance field of +the implementing class, in an associated object with which there is a +one-to-one mapping, or in a static field of another class accessed by a +static method. In the JOGL project, for example, each GLImpl instance +has an associated GLContext in an instance field called "\_context", so +the associated directive is +`GetProcAddressTableExpr _context.getGLProcAddressTable()`. In the JOAL +project, the ProcAddressTables are currently held in a separate class +accessed via static methods, so one of the associated directives is +`GetProcAddressTableExpr ALProcAddressLookup.getALCProcAddressTable()`. + +**<span id="ProcAddressNameExpr">ProcAddressNameExpr</span>** +Syntax: `ProcAddressNameExpr [expression]` +(required) Defines the mapping from function name to function pointer +typedef to be able to properly identify this function as needing +call-through-function-pointer semantics. The supplied expression uses a +set of simple commands to describe certain operations on the function +name: + +- `$UpperCase(arg)` converts the argument to uppercase. "UpperCase" is + case-insensitive. +- `$LowerCase(arg)` converts the argument to lowercase. "LowerCase" is + case-insensitive. +- `{0}` represents the name of the function. +- Any other string represents a constant string. +- Concatenation is implicit. + +The corresponding ProcAddressNameExpr for the OpenGL extension functions +as described at the start of this section is +`PFN $UPPERCASE({0}) PROC`. The +ProcAddressNameExpr for the OpenAL functions as described at the start +of this section is `LP $UPPERCASE({0})`. + +**<span id="ProcAddressTableClassName">ProcAddressTableClassName</span>** +Syntax: `ProcAddressTableClassName [class name]` +(optional) Specifies the class name into which the table containing the +function pointers will be emitted. Defaults to "ProcAddressTable". + +**<span id="ProcAddressTablePackage">ProcAddressTablePackage</span>** +Syntax: +`ProcAddressTablePackage [package name] (no trailing semicolon)` +(optional) Specifies the package into which to produce the +ProcAddressTable for the current set of APIs. Defaults to the +implementation package specified by the [ImplPackage](#ImplPackage) +directive. + +**<span id="SkipProcAddressGen">SkipProcAddressGen</span>** +Syntax: `SkipProcAddressGen [function name]` +(optional) Indicates that the default behavior of +call-through-function-pointer should be skipped for this function +despite the fact that it has an associated function pointer typedef in +the header. + +## <span id="Chapter3">Chapter 3 - Configuration File Examples</span> + +### <span id="SecSimplest">Simplest possible example</span> + +Files: + +- [function.c](example1/function.c) +- [function.h](example1/function.h) +- [function.cfg](example1/function.cfg) +- [gen.sh](example1/gen.sh) + +This example shows the simplest possible usage of GlueGen; a single +routine taking as arguments and returning only primitive types. The +signature of the C function we are interested in binding is + + int one_plus(int a); + + +To bind this function to Java, we only need a configuration file with +very basic settings, indicating the style of glue code emission, the +package and class into which the glue code will be generated, and the +output directories for the Java and native code. The contents of the +configuration file are as follows: + + Package testfunction + Style AllStatic + JavaClass TestFunction + JavaOutputDir gensrc/java + NativeOutputDir gensrc/native + + +GlueGen can then be invoked with approximately the following command +line: + + java -cp gluegen.jar:antlr.jar com.jogamp.gluegen.GlueGen \ + -I. -Ecom.jogamp.gluegen.JavaEmitter -Cfunction.cfg function.h + + +The resulting Java and native code needs to be compiled, and the +application needs to load the native library for the Java binding before +attempting to invoke the native method by calling `System.load()` or +`System.loadLibrary()`. + +### <span id="SecArrays">Arrays and buffers</span> + +Files: + +- [function.c](example2/function.c) +- [function.h](example2/function.h) +- [function.cfg](example2/function.cfg) +- [gen.sh](example2/gen.sh) + +This example shows how C primitive arrays are bound to Java. The header +file contains three functions to bind: + + float process_data(float* data, int n); + void set_global_data(float* data); + float process_global_data(int n); + + +The semantics of `process_data` are that it takes in a pointer to a set +of primitive `float` values and the number of elements in the array and +performs some operation on them, returning a floating-point value as the +result. Afterward the passed data is no longer referenced. + +`set_global_data`, on the other hand, takes a pointer to the data and +stores it persistently in the C code. `process_global_data` then accepts +as argument the number of elements to process from the previously-set +global data, performs this processing and returns a result. The global +data may be accessed again afterward. As an example, these kinds of +semantics are used in certain places in the OpenGL API. + +From a Java binding standpoint, `process_data` may accept data stored +either inside the Java heap (in the form of a `float[]` or non-direct +`FloatBuffer`) or outside the Java heap (in the form of a direct +`FloatBuffer`), because it does not access the data after the function +call has completed and therefore would not be affected if garbage +collection moved the data after the function call was complete. However, +`set_global_data` can cause the passed data to be accessed after the +function call is complete, if `process_global_data` is called. Therefore +the data passed to `set_global_data` may not reside in the Java +garbage-collected heap, but must reside outside the heap in the form of +a direct `FloatBuffer`. + +It is straightforward to take into account these differences in +semantics in the configuration file using the +[NioDirectOnly](#NioDirectOnly) directive: + + # The semantics of set_global_data imply that + # only direct Buffers are legal + NioDirectOnly set_global_data + + +Note the differences in the generated Java-side overloadings for the two +functions: + + public static void process_data(java.nio.FloatBuffer data, int n) {...} + public static void process_data(float[] data, int data_offset, int n) {...} + public static void set_global_data(java.nio.FloatBuffer data) {...} + + +No overloading is produced for `set_global_data` taking a `float[]`, as +it can not handle data residing in the Java heap. Further, the generated +glue code will verify that any `FloatBuffer` passed to this routine is +direct, throwing a `RuntimeException` if not. The type of the exception +thrown in this and other cases may be changed with the +[RuntimeExceptionType](#RuntimeExceptionType) directive. + +### <span id="SecString">String handling</span> + +Files: + +- [function.h](example3/function.h) +- [function.cfg](example3/function.cfg) +- [gen.sh](example3/gen.sh) + +This example shows how to pass and return C strings. The functions +involved are a bit contrived, as nobody would ever need to bind the C +library's string handling routines to Java, but they do illustrate +situations in which Java strings might need to be passed to C and C +strings returned to Java. As an example, both styles of function are +present in the OpenGL and OpenAL APIs. + +The included source code exposes two functions to Java: + + size_t strlen(const char* str); + char* strstr(const char* str1, const char* str2); + + +Note that we might just as easily parse the C standard library's +`string.h` header file to pick up these function declarations. However +for the purposes of this example it is easier to extract just the +functions we need. + +Note that the [function.h](example3/function.h) header file contains a +typedef for `size_t`. This is needed because GlueGen does not inherently +know about this data type. An equivalent data type for the purposes of +this example is `int`, so we choose to tell GlueGen to use that data +type in place of `size_t` while generating glue code. + +The following directive in the configuration file tells GlueGen that +`strlen` takes a string as argument 0 (the first argument): + + ArgumentIsString strlen 0 + + +The following directive tells GlueGen that `strstr` takes two strings as +its arguments: + + ArgumentIsString strstr 0 1 + + +Finally, the following directive tells GlueGen that `strstr` returns a +string instead of an array of bytes: + + ReturnsString strstr + + +We also use the [CustomCCode](#CustomCCode) directive to cause the +`string.h` header file to be \#included in the generated glue code: + + CustomCCode /* Include string.h header */ + CustomCCode #include <string.h> + + +Now the bindings of these two functions to Java look as expected: + + public static native int strlen(java.lang.String str); + public static native java.lang.String strstr(java.lang.String str1, java.lang.String str2); + + +Note that the [ReturnsString](#ReturnsString) directive does not +currently correctly handle the case where the `char*` returned from C +needs to be explicitly freed. As an example, a binding of the C function +`strdup` using a ReturnsString directive would cause a C heap memory +leak. + +### <span id="SecMemory">Memory allocation</span> + +Files: + +- [function.c](example4/function.c) +- [function.h](example4/function.h) +- [function.cfg](example4/function.cfg) +- [gen.sh](example4/gen.sh) + +This example shows how memory allocation is handled when binding C to +Java. It gives the example of a custom memory allocator being bound to +Java; this is a construct that at least at one point was present in +OpenGL in the NV_vertex_array_range extension. + +The two functions we are exposing to Java are as follows: + + void* custom_allocate(int num_bytes); + void custom_free(void* data); + + +The Java-side return type of `custom_allocate` will necessarily be a +`ByteBuffer`, as that is the only useful way of interacting with +arbitrary memory produced by C. The question is how to inform the glue +code generator of the size of the returned sequence of memory. The +semantics of `custom_allocate` are obvious to the programmer; the +incoming `num_bytes` argument specifies the amount of returned memory. +We tell GlueGen this fact using the +[ReturnValueCapacity](#ReturnValueCapacity) directive: + + # The length of the returned ByteBuffer from custom_allocate is + # specified as the argument + ReturnValueCapacity custom_allocate {0} + + +Note that we name incoming argument 0 with the MessageFormat specifier +"{0}" rather than the explicit name of the parameter ("num_bytes") for +generality, in case the header file is changed later. + +Because `custom_free` will only ever receive Buffers produced by +custom_allocate, we use the [NioDirectOnly](#NioDirectOnly) directive to +prevent accidental usage with the wrong kind of Buffer: + + # custom_free will only ever receive a direct Buffer + NioDirectOnly custom_free + + +The generated Java APIs for these functions are as follows: + + public static java.nio.ByteBuffer custom_allocate(int num_bytes) {...} + public static void custom_free(java.nio.Buffer data) {...} + + +### <span id="SecStructs">Ingoing and outgoing structs</span> + +Files: + +- [function.c](example5/function.c) +- [function.h](example5/function.h) +- [function.cfg](example5/function.cfg) +- [gen.sh](example5/gen.sh) + +This example shows how GlueGen provides access to C structs and supports +both passing them to and returning them from C functions. The header +file defines a sample data structure that might describe the bit depth +of a given screen: + + typedef struct { + int redBits; + int greenBits; + int blueBits; + } ScreenInfo; + + +Two functions are defined which take and return this data type: + + ScreenInfo* default_screen_depth(); + void set_screen_depth(ScreenInfo* info); + + +The semantics of `default_screen_depth()` are that it returns a pointer +to some static storage which does not need to be freed, which describes +the default screen depth. `set_screen_depth()` is a hypothetical +function which would take a newly-allocated `ScreenInfo` and cause the +primary display to switch to the specified bit depth. + +The only additional information we need to tell GlueGen, beyond that in +the header file, is how much storage is returned from +`default_screen_depth()`. Note the semantic ambiguity, where it might +return a pointer to a single `ScreenInfo` or a pointer to an array of +`ScreenInfo`s. We tell GlueGen that the return value is a single value +with the [ReturnValueCapacity](#ReturnValueCapacity) directive, +similarly to the [memory allocation](#SecMemory) example above: + + # Tell GlueGen that default_screen_depth() returns a pointer to a + # single ScreenInfo + ReturnValueCapacity default_screen_depth sizeof(ScreenInfo) + + +Note that if `default_screen_depth` had returned newly-allocated +storage, it would be up to the user to expose a `free()` function to +Java and call it when necessary. + +GlueGen automatically generates a Java-side `ScreenInfo` class which +supports not only access to any such objects returned from C, but also +allocation of new `ScreenInfo` structs which can be passed +(persistently) down to C. The Java API for the ScreenInfo class looks +like this: + + public abstract class ScreenInfo { + public static ScreenInfo create(); + public abstract ScreenInfo redBits(int val); + public abstract int redBits(); + ... + } + + +The `create()` method allocates a new ScreenInfo struct which may be +passed, even persistently, out to C. Its C-heap storage will be +automatically reclaimed when the Java-side ScreenInfo object is no +longer reachable, as it is backed by a direct New I/O `ByteBuffer`. The +fields of the struct are exposed as methods which supply both getters +and setters. + +### <span id="SecStructArrays">Returned arrays of structs</span> + +Files: + +- [function.h](example6/function.h) +- [function.cfg](example6/function.cfg) +- [gen.sh](example6/gen.sh) + +This example, taken from JOGL's X11 binding, illustrates how to return +an array of structs from C to Java. The `XGetVisualInfo` function from +the X library has the following signature: + + XVisualInfo *XGetVisualInfo( + Display* display, + long vinfo_mask, + XVisualInfo* vinfo_template, + int* nitems_return + ); + + +Note that the `XVisualInfo` data structure itself contains many +elements, including a pointer to the current visual. We use the +following trick in the header file to cause GlueGen to treat the +`Display*` in the above signature as well as the `Visual*` in the +`XVisualInfo` as opaque pointers: + + typedef struct {} Display; + typedef struct {} Visual; + typedef unsigned long VisualID; + + typedef struct { + Visual *visual; + VisualID visualid; + int screen; + int depth; + int c_class; /* C++ */ + unsigned long red_mask; + unsigned long green_mask; + unsigned long blue_mask; + int colormap_size; + int bits_per_rgb; + } XVisualInfo; + + +`XGetVisualInfo` returns all of the available pixel formats in the form +of `XVisualInfo`s which match a given template. `display` is the current +connection to the X server. `vinfo_mask` indicates which fields from the +template to match against. `vinfo_template` is a partially filled-in +`XVisualInfo` specifying the characteristics to match. `nitems_return` +is a pointer to an integer indicating how many `XVisualInfo`s were +returned. The return value, rather than being a pointer to a single +`XVisualInfo`, is a pointer to the start of an array of `XVisualInfo` +data structures. + +There are two basic steps to being able to return this array properly to +Java using GlueGen. The first is creating a direct ByteBuffer of the +appropriate size in the autogenerated JNI code. The second is slicing up +this ByteBuffer appropriately in order to return an `XVisualInfo[]` at +the Java level. + +In the autogenerated JNI code, after the call to `XGetVisualInfo` is +made, the outgoing `nitems_return` value points to the number of +elements in the returned array, which indicates the size of the direct +ByteBuffer which would need to wrap these elements. However, if we look +at the implementation of one of the generated glue code variants for +this method (specifically, the one taking an `int[]` as the third +argument), we can see a problem in trying to access this value in the C +code: + + JNIEXPORT jobject JNICALL + Java_testfunction_TestFunction_XGetVisualInfo1__Ljava_nio_ByteBuffer_2JLjava_nio_ByteBuffer_2Ljava_lang_Object_2I( + JNIEnv *env, jclass _unused, jobject arg0, jlong arg1, jobject arg2, jobject arg3, jint arg3_byte_offset) { + ... + int * _ptr3 = NULL; + ... + if (arg3 != NULL) { + _ptr3 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, arg3, NULL)) + arg3_byte_offset); + } + _res = XGetVisualInfo((Display *) _ptr0, (long) arg1, (XVisualInfo *) _ptr2, (int *) _ptr3); + if (arg3 != NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, arg3, _ptr3, 0); + } + if (_res == NULL) return NULL; + return (*env)->NewDirectByteBuffer(env, _res, ??? What to put here ???); + } + + +Note that at the point of the statement "What to put here?" the pointer +to the storage of the `int[]`, `_ptr3`, has already been released via +`ReleasePrimitiveArrayCritical`. This means that it may not be +referenced at the point needed in the code. + +To solve this problem we use the +[TemporaryCVariableDeclaration](#TemporaryCVariableDeclaration) and +[TemporaryCVariableAssignment](#TemporaryCVariableAssignment) +directives. We want to declare a persistent integer variable down in the +C code and assign the returned array length to that variable before the +primitive array is released. While in order to do this we unfortunately +need to know something about the structure of the autogenerated JNI +code, at least we don't have to hand-edit it afterward. We add the +following directives to the configuration file: + + # Get returned array's capacity from XGetVisualInfo to be correct + TemporaryCVariableDeclaration XGetVisualInfo int count; + TemporaryCVariableAssignment XGetVisualInfo count = _ptr3[0]; + + +Now in the autogenerated JNI code the variable "count" will contain the +number of elements in the returned array. We can then reference this +variable in a [ReturnValueCapacity](#ReturnValueCapacity) directive: + + ReturnValueCapacity XGetVisualInfo count * sizeof(XVisualInfo) + + +At this point the `XGetVisualInfo` binding will return a Java-side +`XVisualInfo` object whose backing ByteBuffer is the correct size. We +now have to inform GlueGen that the underlying ByteBuffer represents not +a single `XGetVisualInfo` struct, but an array of them, using the +[ReturnedArrayLength](#ReturnedArrayLength) directive. This conversion +is performed on the Java side of the autogenerated code. Here, the first +element of either the passed `IntBuffer` or `int[]` contains the number +of elements in the returned array. (Alternatively, we could examine the +length of the ByteBuffer returned from C to Java and divide by +`XVisualInfo.size()`.) Because there are two overloadings produced by +GlueGen for this method, if we reference the `nitems_return` argument in +a [ReturnedArrayLength](#ReturnedArrayLength) directive, we need to +handle not only the differing data types properly (`IntBuffer` vs. +`int[]`), but also the fact that both the integer array and its offset +value are substituted for any reference to the fourth argument. + +To solve this problem, we define a pair of private helper functions +whose purpose is to handle this overloading. + + CustomJavaCode TestFunction private static int getFirstElement(IntBuffer buf) { + CustomJavaCode TestFunction return buf.get(buf.position()); + CustomJavaCode TestFunction } + CustomJavaCode TestFunction private static int getFirstElement(int[] arr, + CustomJavaCode TestFunction int offset) { + CustomJavaCode TestFunction return arr[offset]; + CustomJavaCode TestFunction } + + +Now we can simply write for the returned array length: + + ReturnedArrayLength XGetVisualInfo getFirstElement({3}) + + +That's all that is necessary. GlueGen will then produce the following +Java-side overloadings for this function: + + public static XVisualInfo[] XGetVisualInfo(Display arg0, + long arg1, + XVisualInfo arg2, + java.nio.IntBuffer arg3); + public static XVisualInfo[] XGetVisualInfo(Display arg0, + long arg1, + XVisualInfo arg2, + int[] arg3, int arg3_offset); + + +As it happens, we don't really need the Display and Visual data +structures to be produced; they can be treated as `long`s on the Java +side. Therefore we can add the following directives to the configuration +file: + + # We don't need the Display and Visual data structures to be + # explicitly exposed + Opaque long Display * + Opaque long Visual * + # Ignore the empty Display and Visual data structures (though made + # opaque, the references from XVisualInfo and elsewhere are still + # traversed) + Ignore Display + Ignore Visual + + +The final generated Java API is the following: + + public static XVisualInfo[] XGetVisualInfo(long arg0, + long arg1, + XVisualInfo arg2, + java.nio.IntBuffer arg3); + public static XVisualInfo[] XGetVisualInfo(long arg0, + long arg1, + XVisualInfo arg2, + int[] arg3, int arg3_offset); + + +### <span id="SecPointerArrays">Returned arrays of pointers</span> + +Files: + +- [function.h](example7/function.h) +- [function.cfg](example7/function.cfg) +- [gen.sh](example7/gen.sh) + +As with the [example above](#SecStructArrays), this example is taken +from JOGL's X11 binding. Here we show how to expose to Java a C routine +returning an array of pointers to a data structure. + +The declaration of the function we are binding is as follows: + + typedef struct __GLXFBConfigRec *GLXFBConfig; + + GLXFBConfig *glXChooseFBConfig( Display *dpy, int screen, + const int *attribList, int *nitems ); + + +This function is used during allocation of a hardware-accelerated +off-screen surface ("pbuffer") on X11 platforms; its exact meaning is +not important. The semantics of the arguments and return value are as +follows. As in the [previous example](#SecStructArrays), it accepts a +connection to the current X display as one argument. The screen of this +display is the second argument. The `attribList` is a zero-terminated +list of integer attributes; because it is zero-terminated, the length of +this list is not passed to the function. As in the previous example, the +`nitems` argument points to an integer into which the number of returned +`GLXFBConfig` objects is placed. The return value is an array of +`GLXFBConfig` objects. + +Because the `GLXFBConfig` data type is typedefed as a pointer to an +opaque (undefined) struct, the construct `GLXFBConfig*` is implicitly a +"pointer-to-pointer" type. GlueGen automatically assumes this is +convertible to a Java-side array of accessors to structs. The only +configuration necessary is to tell GlueGen the length of this array. + +As in the previous example, we use the +[TemporaryCVariableDeclaration](#TemporaryCVariableDeclaration) and +[TemporaryCVariableAssignment](#TemporaryCVariableAssignment) directives +to capture the length of the returned array: + +TemporaryCVariableDeclaration glXChooseFBConfig int count; +TemporaryCVariableAssignment glXChooseFBConfig count = \_ptr3\[0\]; + +The structure of the generated glue code for the return value is subtly +different than in the previous example. The question in this case is not +whether the return value is a pointer to a single object vs. a pointer +to an array of objects; it is what the length of the returned array is, +since we already know that the return type is pointer-to-pointer and is +therefore an array. We use the [ReturnValueLength](#ReturnValueLength) +directive for this case: + + ReturnValueLength glXChooseFBConfig count + + +We add similar Opaque directives to the previous example to yield the +resulting Java bindings for this function: + + public static GLXFBConfig[] glXChooseFBConfig(long dpy, + int screen, + java.nio.IntBuffer attribList, + java.nio.IntBuffer nitems); + public static GLXFBConfig[] glXChooseFBConfig(long dpy, + int screen, + int[] attribList, int attribList_offset, + int[] nitems, int nitems_offset); + + +Note that because the GLXFBConfig data type is returned as an element of +an array, we can not use the Opaque directive to erase this data type to +`long` as we did with the `Display` data type. + diff --git a/doc/misc/macos_nativelib_dependencies.html b/doc/misc/macos_nativelib_dependencies.html new file mode 100644 index 0000000..b4214ae --- /dev/null +++ b/doc/misc/macos_nativelib_dependencies.html @@ -0,0 +1,485 @@ +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang=""> +<head> + <meta charset="utf-8" /> + <meta name="generator" content="pandoc" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> + <title>macos_nativelib_dependencies.md</title> + <style> + div#header, header + { + + border-bottom: 1px solid #aaa; + margin-bottom: 0.5em; + } + + .title + { + text-align: center; + } + + .author, .date + { + text-align: center; + } + + div#TOC, nav#TOC + { + + border-bottom: 1px solid #aaa; + margin-bottom: 0.5em; + } + + nav#TOC { + margin-bottom: var(--line-height); + + padding-bottom: 0.5rem; + } + + nav#TOC input { + display: none; + } + + nav#TOC label { + color: var(--color-link); + cursor: pointer; + } + + nav#TOC > ul { + display: none; + } + + nav#TOC > input:checked + ul { + display: block; + } + + @media print + { + div#TOC, nav#TOC + { + + display: none; + } + } + + div.content + { + color: #111111; + font-size: 14px; + line-height: 1.6; + } + + div#cgit a + { + color: #1212a0; + } + + div#cgit a.sourceLine + { + color: #111111; + } + + h1, h2, h3, h4, h5, h6 + { + font-family: "Helvetica Neue", Helvetica, "Liberation Sans", Calibri, Arial, sans-serif; + + page-break-after: avoid; + + margin: 20px 0 10px; + padding: 0; + } + + h2 { + border-bottom: 1px solid #ccc; + } + + div div + { + + } + + section section + { + margin-left: 2em; + } + + p {} + + blockquote + { + font-style: italic; + } + + li + { + } + + li > p + { + margin-top: 1em; + } + + ul + { + } + + ul li + { + } + + ol + { + } + + ol li + { + } + + hr {} + + sub + { + } + + sup + { + } + + em + { + } + + em > em + { + font-style: normal; + } + + strong + { + } + + a + { + + text-decoration: none; + } + + @media screen + { + a:hover + { + + text-decoration: underline; + } + } + + @media print + { + a { + + color: black; + background: transparent; + } + + a[href^="http://"]:after, a[href^="https://"]:after + { + + content: " (" attr(href) ") "; + font-size: 90%; + } + } + + img + { + + vertical-align: middle; + } + + div.figure + { + + margin-left: auto; + margin-right: auto; + text-align: center; + font-style: italic; + } + + p.caption + { + + } + + pre, code + { + background-color: #f8f8f8; + + white-space: pre-wrap; + white-space: -moz-pre-wrap !important; + white-space: -pre-wrap; + white-space: -o-pre-wrap; + word-wrap: break-word; + + } + + pre + { + + padding: 0.5em; + border-radius: 5px; + + background-color: #f8f8f8; + border: 1px solid #ccc; + font-size: 13px; + line-height: 19px; + overflow: auto; + padding: 6px 10px; + + margin-left: 0.5em; + margin-right: 0.5em; + } + + @media screen + { + pre + { + + white-space: pre; + overflow: auto; + + border: 1px dotted #777; + } + } + + code + { + } + + p > code, li > code + { + + padding-left: 2px; + padding-right: 2px; + } + + li > p code + { + + padding: 2px; + } + + span.math + { + + } + + div.math + { + } + + span.LaTeX + { + } + + eq + { + } + + table + { + border-collapse: collapse; + border-spacing: 0; + + margin-left: auto; + margin-right: auto; + } + + thead + { + border-bottom: 1pt solid #000; + background-color: #eee; + } + + tr.header + { + } + + tbody + { + } + + tr { + } + tr.odd:hover, tr.even:hover + { + background-color: #eee; + } + + tr.odd {} + tr.even {} + + td, th + { + vertical-align: top; + vertical-align: baseline; + padding-left: 0.5em; + padding-right: 0.5em; + padding-top: 0.2em; + padding-bottom: 0.2em; + } + th + { + font-weight: bold; + } + + tfoot + { + } + + caption + { + caption-side: top; + border: none; + font-size: 0.9em; + font-style: italic; + text-align: center; + margin-bottom: 0.3em; + padding-bottom: 0.2em; + } + + dl + { + border-top: 2pt solid black; + padding-top: 0.5em; + border-bottom: 2pt solid black; + } + + dt + { + font-weight: bold; + } + + dd+dt + { + border-top: 1pt solid black; + padding-top: 0.5em; + } + + dd + { + margin-bottom: 0.5em; + } + + dd+dd + { + border-top: 1px solid black; + } + + a.footnote, a.footnoteRef { + font-size: small; + vertical-align: text-top; + } + + a[href^="#fnref"], a.reversefootnote + { + } + + @media print + { + a[href^="#fnref"], a.reversefootnote + { + + display: none; + } + } + + div.footnotes + { + } + + div.footnotes li[id^="fn"] + { + } + + @media print + { + .noprint + { + display:none; + } + } + </style> +</head> +<body> +<nav id="TOC" role="doc-toc"> + <strong>Contents</strong><label for="contents">⊕</label> + <input type="checkbox" id="contents"> + <ul> + <li><a href="#loading-a-macos-native-librarys-dependencies">Loading a + MacOS Native Library's Dependencies</a> + <ul> + <li><a + href="#just-use-dynamic-loading-via-gluegens-procaddresstable">Just + use dynamic loading via GlueGen's ProcAddressTable</a></li> + <li><a href="#cant-pass-dyld_library_path-to-usrbinjava">Can't pass + <code>DYLD_LIBRARY_PATH</code> to <code>/usr/bin/java</code></a></li> + <li><a + href="#workaround-inability-to-pass-dyld_library_path-to-usrbinjava">Workaround + inability to pass <code>DYLD_LIBRARY_PATH</code> to + <code>/usr/bin/java</code></a> + <ul> + <li><a + href="#use-explicit-openjdktemurin-jdk-java-executable-path">Use + explicit OpenJDK/Temurin JDK <code>java</code> executable + path</a></li> + <li><a href="#using-loader_path-within-dependent-library">Using + ``@loader_path` within dependent library</a></li> + </ul></li> + </ul></li> + </ul> +</nav> +<h1 id="loading-a-macos-native-librarys-dependencies">Loading a MacOS +Native Library's Dependencies</h1> +<p>Assume we have <code>libBindingtest1p1.dylib</code>, which links to +<code>libtest1.dylib</code>, i.e. requires the OS native library to load +<code>libtest1.dylib</code> to resolve symbols.</p> +<p>Usually we just se <code>DYLD_LIBRARY_PATH</code> including the path +where <code>libtest1.dylib</code> is located and we are good to go.</p> +<h2 id="just-use-dynamic-loading-via-gluegens-procaddresstable">Just use +dynamic loading via GlueGen's ProcAddressTable</h2> +<p>Note, the above problem does not occur when using GlueGen's +ProcAddressTable, i.e. loading the underlying tool library +<code>libtest2.dylib</code> w/ dlopen and passing all symbols to the JNI +library <code>libBindingtest1p2.dylib</code>.</p> +<h2 id="cant-pass-dyld_library_path-to-usrbinjava">Can't pass +<code>DYLD_LIBRARY_PATH</code> to <code>/usr/bin/java</code></h2> +<p>This is supposed to be related to MacOS's +<code>System Integrity Protect (SIP)</code>.</p> +<h2 +id="workaround-inability-to-pass-dyld_library_path-to-usrbinjava">Workaround +inability to pass <code>DYLD_LIBRARY_PATH</code> to +<code>/usr/bin/java</code></h2> +<h3 id="use-explicit-openjdktemurin-jdk-java-executable-path">Use +explicit OpenJDK/Temurin JDK <code>java</code> executable path</h3> +<p>Interestingly passing <code>DYLD_LIBRARY_PATH</code> works using the +explicit <code>java</code> executable path, set by default as +follows:</p> +<pre><code># MacOS: Select JVM path to allow DYLD_LIBRARY_PATH +JAVA_HOME=`/usr/libexec/java_home -version 17` +PATH=$JAVA_HOME/bin:$PATH +export JAVA_HOME PATH</code></pre> +<h3 id="using-loader_path-within-dependent-library">Using +``@loader_path` within dependent library</h3> +<p>Set location of referenced library <code>libtest1.dylib</code> to +same path of dependent library <code>libBindingtest1p1.dylib</code> +using <code>@loader_path</code>.</p> +<pre><code>cd build-macosx/test/build/natives/ +otool -L libBindingtest1p1.dylib +install_name_tool -change libtest1.dylib @loader_path/libtest1.dylib libBindingtest1p1.dylib +otool -L libBindingtest1p1.dylib </code></pre> +<p>Further we could try <code>@executable_path</code> and +<code>@rpath</code>.</p> +<p>See <a +href="https://www.joyfulbikeshedding.com/blog/2021-01-13-alternative-to-macos-dyld-library-path.html">An +alternative to macOS's DYLD_LIBRARY_PATH</a>.</p> +</body> +</html> diff --git a/doc/misc/macos_nativelib_dependencies.md b/doc/misc/macos_nativelib_dependencies.md index 70d0973..6592c44 100644 --- a/doc/misc/macos_nativelib_dependencies.md +++ b/doc/misc/macos_nativelib_dependencies.md @@ -10,10 +10,23 @@ Note, the above problem does not occur when using GlueGen's ProcAddressTable, i.e. loading the underlying tool library `libtest2.dylib` w/ dlopen and passing all symbols to the JNI library `libBindingtest1p2.dylib`. -## Can't pass `DYLD_LIBRARY_PATH` to `java` +## Can't pass `DYLD_LIBRARY_PATH` to `/usr/bin/java` This is supposed to be related to MacOS's `System Integrity Protect (SIP)`. -## Workaround inability to pass `DYLD_LIBRARY_PATH` to `java` +## Workaround inability to pass `DYLD_LIBRARY_PATH` to `/usr/bin/java` + +### Use explicit OpenJDK/Temurin JDK `java` executable path + +Interestingly passing `DYLD_LIBRARY_PATH` works using the +explicit `java` executable path, set by default as follows: + +``` +# MacOS: Select JVM path to allow DYLD_LIBRARY_PATH +JAVA_HOME=`/usr/libexec/java_home -version 17` +PATH=$JAVA_HOME/bin:$PATH +export JAVA_HOME PATH +``` + ### Using ``@loader_path` within dependent library Set location of referenced library `libtest1.dylib` to same path of dependent library `libBindingtest1p1.dylib` diff --git a/make/scripts/md2html_update.sh b/make/scripts/md2html_update.sh new file mode 100755 index 0000000..85e237a --- /dev/null +++ b/make/scripts/md2html_update.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +set -x + +sdir=`dirname $(readlink -f $0)` +rdir=$sdir/../.. + +pandoc_md2html_local.sh $rdir/doc/GlueGen_Mapping.md > $rdir/doc/GlueGen_Mapping.html +pandoc_md2html_local.sh $rdir/doc/manual/index.md > $rdir/doc/manual/index.html +pandoc_md2html_local.sh $rdir/doc/misc/macos_nativelib_dependencies.md > $rdir/doc/misc/macos_nativelib_dependencies.html +pandoc_md2html_local.sh $rdir/doc/JogAmpMacOSVersions.md > $rdir/doc/JogAmpMacOSVersions.html |