diff options
Diffstat (limited to 'doc/manual')
-rwxr-xr-x | doc/manual/index.html | 4542 |
1 files changed, 2275 insertions, 2267 deletions
diff --git a/doc/manual/index.html b/doc/manual/index.html index 0506bde..64385f1 100755 --- a/doc/manual/index.html +++ b/doc/manual/index.html @@ -1,4 +1,4 @@ -<!DOCTYPE html PUBliC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<!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" /> @@ -23,2279 +23,2287 @@ <li><a href="../../../deployment/gluegen-next/javadoc/">JavaDoc</a></li> </ul> </div> - <div id="main" class="fill"> - - -<H1>GlueGen Manual</H1> - -<H2> Table of Contents </H2> - -<a href="#Chapter1">Chapter 1</a> - Introduction -<UL> -<LI> <a href = "#SecIntroduction">Introduction</a> -<LI> <a href = "#SecStructure">Structure of the Generated Glue Code</a> -<LI> <a href = "#SecUnique">Unique Features</a> -<LI> <a href = "#SecBackground">Background and Design Principles</a> -</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> - </UL> -<LI> <a href = "#SecBasic">Basic Operation</a> -<LI> <a href = "#SecAnt">Running GlueGen as an Ant Task</a> -<LI> <a href = "#SecPCPP">PCPP</a> -<LI> <a href = "#SecError">Error Reporting</a> -<LI> <a href = "#SecStub">Stub Headers</a> -<LI> <a href = "#Sec32">32- and 64-bit Considerations</a> -<LI> <a href = "#SecOpaque">Opaque Directives</a> -<LI> <a href = "#SecSubstitution">Argument Name Substitution</a> -<LI> <a href = "#SecConfiguration">Configuration File Directives</a> - <UL> - <LI> <a href = "#SecJavaEmitter">JavaEmitter Configuration</a> - <LI> <a href = "#SecProcAddressEmitter">ProcAddressEmitter Configuration</a> - </UL> -</UL> - -<a href="#Chapter3">Chapter 3</a> - Configuration File Examples<BR> -<UL> -<LI> <a href = "#SecSimplest">Simplest possible example</a> -<LI> <a href = "#SecArrays">Arrays and buffers</a> -<LI> <a href = "#SecString">String handling</a> -<LI> <a href = "#SecMemory">Memory allocation</a> -<LI> <a href = "#SecStructs">Ingoing and outgoing structs</a> -<LI> <a href = "#SecStructArrays">Returned arrays of structs</a> -<LI> <a href = "#SecPointerArrays">Returned arrays of pointers</a> -</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. - -<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> -<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> 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> 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. - - </UL> - -<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> Similar rules for <code>void*</code> return values apply to - those for pointers to typed primitives. - - </UL> - -<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> 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> 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> <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> 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. - -</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> 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> 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. - - </UL> - -</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://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: - -<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> Avoid touching the generated glue code completely. - -<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> 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> As the tool is targetting the Java programming language, build - the tool in the Java programming language. - -</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> -<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 via Subversion: - -<pre> - svn co https://gluegen.dev.java.net/svn/gluegen/trunk gluegen --username [username] -</pre> - -To build GlueGen, first download the ANTLR jar file from <a -href="http://antlr.org/">antlr.org</a>. Currently GlueGen is only -compatible with ANTLR releases up to 2.7.x and does not work with -ANTLR 3.x. (NOTE: do not place the ANTLR jar file in the Extensions -directory of the JRE or JDK, as this will cause the build to fail.) -Next, copy <code>make/gluegen.properties</code> from the GlueGen -workspace to your home directory (pointed to by the Java system -property <code>user.home</code>; on Windows this is -e.g. <code>C:\Documents and Settings\username</code>). Edit the copy -of gluegen.properties in your home directory to point the -<code>antlr.jar</code> property to the location of the ANTLR jar file -on your local disk. Finally, cd to the <code>make/</code> subdirectory -and type "ant". Ant 1.6.x or later is required. - -<H4><a name="SecCommon">Common Build Problems</a></H4> - -<P> - -<dl> -<dt> <strong>CharScanner; panic: ClassNotFoundException: com.sun.gluegen.cgram.CToken</strong> -<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. -</dl> - -</P> - -<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: - -<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> -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.sun.gluegen.GlueEmitter</code> interface. If this - option is not specified, a - <code>com.sun.gluegen.JavaEmitter</code> will be used by default. - -<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> [ 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. -</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: - -<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.sun.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.sun.gluegen.JavaEmitter"> + <div id="main"> + <div id="text" class="fill"> + <h1>GlueGen Manual</h1> + + <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 = "#SecPCPP">PCPP</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://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 via Subversion: + + <pre> + svn co https://gluegen.dev.java.net/svn/gluegen/trunk gluegen --username [username] + </pre> + + To build GlueGen, first download the ANTLR jar file from <a + href="http://antlr.org/">antlr.org</a>. Currently GlueGen is only + compatible with ANTLR releases up to 2.7.x and does not work with + ANTLR 3.x. (NOTE: do not place the ANTLR jar file in the Extensions + directory of the JRE or JDK, as this will cause the build to fail.) + Next, copy <code>make/gluegen.properties</code> from the GlueGen + workspace to your home directory (pointed to by the Java system + property <code>user.home</code>; on Windows this is + e.g. <code>C:\Documents and Settings\username</code>). Edit the copy + of gluegen.properties in your home directory to point the + <code>antlr.jar</code> property to the location of the ANTLR jar file + on your local disk. Finally, cd to the <code>make/</code> subdirectory + and type "ant". Ant 1.6.x or later is required. + + <h4><a name="SecCommon">Common Build Problems</a></h4> + + + <dl> + <dt> <strong>CharScanner; panic: ClassNotFoundException: com.sun.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.sun.gluegen.GlueEmitter</code> interface. If this + option is not specified, a + <code>com.sun.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.sun.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.sun.gluegen.JavaEmitter"> <classpath refid="gluegen.classpath" /> - </gluegen> -</pre> - -Please see the <a href="http://jogl.dev.java.net/">JOGL</a> and <a -href="http://joal.dev.java.net/">JOAL</a> build.xml files for -concrete, though non-trivial, examples of how to invoke GlueGen via -Ant. - -<H3><a name="SecPCPP">PCPP</a></H3> - -<P> - -GlueGen contains and uses a minimal C preprocessor called the "Pseudo -C Pre-Processor", or PCPP. A slightly specialized C preprocessor is -required for correct glue code generation with most libraries. -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, and if the header is processed by a full C -preprocessor then the #define statements will be stripped become -unavailable for processing by the glue code generator. - -</P> -<P> - -PCPP is largely an invisible part of the glue code generation process; -however, it has certain limitations which make it difficult to parse -certain header files. First, it does not support macro evaluation in -any form, so if a header relies on macro evaluation in order to -generate code, PCPP will fail. It is possible that PCPP may fail -silently in this situation, causing GlueGen to simply not produce code -for the associated constructs. If GlueGen's output is not as expected -and there is heavy use of the C preprocessor in the header, run PCPP -against the header directly (PCPP takes simply the -I and filename -arguments accepted by GlueGen) and examine the output. - -</P> -<P> - -Second, PCPP contains only limited support for <code>#if</code> -clauses. Generally speaking, its handling of <code>#if defined(foo) || -defined(bar)</code> constructs is limited to approximately what is -required to handle the OpenGL header files. If the header being parsed -relies on moderately complicated expressions being evaluated by the C -preprocessor, check the output from PCPP and ensure it is as expected. - -</P> -<P> - -Contributions to PCPP would be especially welcome. It would be very -desirable to turn it into a full-blown C preprocessor with simply the -option of passing through #define statements unchanged. - -</P> - -<H3><a name="SecError">Error Reporting</a></H3> - -<P> - -Error reporting by GlueGen's parser is currently less than ideal. -Because PCPP makes <code>#include</code> directives disappear -completely with respect to the C parser (it appears that the -<code>#line</code> directives it emits are not being consumed properly --- an area which needs more investigation), the line numbers reported -in parse failures are incorrect in all but the simplest cases. This -makes it difficult to determine in exactly what header file and on -exactly what construct the C parser failed. - -</P> -<P> - -Fortunately, there is a relatively simple workaround. PCPP can be run -with all of the same -I arguments passed to GlueGen and the result -piped to a new .c file. GlueGen can then be invoked on that .c file -(now containing no <code>#include</code> directives) and the line -numbers on any parse failures will be correct. - -</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: - -<pre> - #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> - -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 <a href="#SecPCPP">minimal 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: - -<pre> - typedef struct _handle* HANDLE; - typedef HANDLE HDC; - typedef HANDLE HWND; -</pre> - -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 - -<pre> - typedef void* LPVOID; -</pre> - -then an Opaque directive stating - -<pre> - Opaque long LPVOID -</pre> - -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 - -<pre> - Opaque long HANDLE -</pre> - -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: - -<pre> - typedef long HANDLE; -</pre> - -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: - -<pre> - typedef struct _handle* HANDLE; -</pre> - -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: - -<pre> - Opaque long HANDLE -</pre> - -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> -<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>. - - -<dt><strong><a name="ArgumentIsString">ArgumentIsString</a></strong> -<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>. - - -<dt><strong><a name="ClassJavadoc">ClassJavadoc</a></strong> -<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. - - -<dt><strong><a name="CustomCCode">CustomCCode</a></strong> -<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. - - -<dt><strong><a name="CustomJavaCode">CustomJavaCode</a></strong> -<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. - - -<dt><strong><a name="EmitStruct">EmitStruct</a></strong> -<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. - - -<dt><strong><a name="GlueGenRuntimePackage">GlueGenRuntimePackage</a></strong> -<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. - - -<dt><strong><a name="Extends">Extends</a></strong> -<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 the <a href="#Implements">Implements</a> -directive. - - -<dt><strong><a name="HierarchicalNativeOutput">HierarchicalNativeOutput</a></strong> -<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. - - -<dt><strong><a name="Ignore">Ignore</a></strong> -<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>. - - -<dt><strong><a name="IgnoreField">IgnoreField</a></strong> -<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. - - -<dt><strong><a name="IgnoreNot">IgnoreNot</a></strong> -<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. - - -<dt><strong><a name="Implements">Implements</a></strong> -<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. - - -<dt><strong><a name="ImplJavaClass">ImplJavaClass</a></strong> -<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>. - - -<dt><strong><a name="ImplPackage">ImplPackage</a></strong> -<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>. - - -<dt><strong><a name="Import">Import</a></strong> -<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. - - -<dt><strong><a name="Include">Include</a></strong> -<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. - - -<dt><strong><a name="IncludeAs">IncludeAs</a></strong> -<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>. - - -<dt><strong><a name="JavaClass">JavaClass</a></strong> -<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>. - - -<dt><strong><a name="JavaEpilogue">JavaEpilogue</a></strong> -<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>. - - -<dt><strong><a name="JavaOutputDir">JavaOutputDir</a></strong> -<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. - - -<dt><strong><a name="JavaPrologue">JavaPrologue</a></strong> -<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>. - - -<dt><strong><a name="ManuallyImplement">ManuallyImplement</a></strong> -<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. - - -<dt><strong><a name="NativeOutputDir">NativeOutputDir</a></strong> -<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>. - - -<dt><strong><a name="NioDirectOnly">NioDirectOnly</a></strong> -<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. - - -<dt><strong><a name="Opaque">Opaque</a></strong> -<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. - - -<dt><strong><a name="Package">Package</a></strong> -<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>. - - -<dt><strong><a name="RangeCheck">RangeCheck</a></strong> -<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. - - -<dt><strong><a name="RangeCheckBytes">RangeCheckBytes</a></strong> -<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. - - -<dt><strong><a name="RenameJavaMethod">RenameJavaMethod</a></strong> -<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. - - -<dt><strong><a name="RenameJavaType">RenameJavaType</a></strong> -<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. - - -<dt><strong><a name="ReturnedArrayLength">ReturnedArrayLength</a></strong> -<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. - - -<dt><strong><a name="ReturnsString">ReturnsString</a></strong> -<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. - -<dt><strong><a name="ReturnValueCapacity">ReturnValueCapacity</a></strong> -<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. - - -<dt><strong><a name="ReturnValueLength">ReturnValueLength</a></strong> -<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. - - -<dt><strong><a name="RuntimeExceptionType">RuntimeExceptionType</a></strong> -<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>. - - -<dt><strong><a name="StructPackage">StructPackage</a></strong> -<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>). - - -<dt><strong><a name="Style">Style</a></strong> -<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. - - -<dt><strong><a name="TemporaryCVariableAssignment">TemporaryCVariableAssignment</a></strong> -<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. - - -<dt><strong><a name="TemporaryCVariableDeclaration">TemporaryCVariableDeclaration</a></strong> -<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. - - -<dt><strong><a name="Unignore">Unignore</a></strong> -<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. - - -<dt><strong><a name="Unimplemented">Unimplemented</a></strong> -<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. - - -</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: - -<pre> - GLAPI void APIENTRY glFogCoordf (GLfloat); -... - typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord); -</pre> - -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: - -<pre> - AL_API void AL_APIENTRY alEnable( ALenum capability ); -... - typedef void (AL_APIENTRY *LPALENABLE)( ALenum capability ); -</pre> - -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="#SecPCPP">PCPP</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> -<dd> Syntax: <code>EmitProcAddressTable [true | false]</code> <br> - -(optional) Indicates whether to emit the ProcAddressTable during glue -code generation. Defaults to false. - - -<dt><strong><a name="ForceProcAddressGen">ForceProcAddressGen</a></strong> -<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) - - -<dt><strong><a name="GetProcAddressTableExpr">GetProcAddressTableExpr</a></strong> -<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>. - - -<dt><strong><a name="ProcAddressNameExpr">ProcAddressNameExpr</a></strong> -<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> <code>$LowerCase(arg)</code> converts the argument to - lowercase. "LowerCase" is case-insensitive. -<LI> <code>{0}</code> represents the name of the function. -<LI> Any other string represents a constant string. -<LI> Concatenation is implicit. -</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>. - - -<dt><strong><a name="ProcAddressTableClassName">ProcAddressTableClassName</a></strong> -<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". - - -<dt><strong><a name="ProcAddressTablePackage">ProcAddressTablePackage</a></strong> -<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. - - -<dt><strong><a name="SkipProcAddressGen">SkipProcAddressGen</a></strong> -<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. - -</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> <a href="example1/function.h">function.h</a> -<LI> <a href="example1/function.cfg">function.cfg</a> -<LI> <a href="example1/gen.sh">gen.sh</a> -</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 - 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.sun.gluegen.GlueGen \ - -I. -Ecom.sun.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> <a href="example2/function.h">function.h</a> -<LI> <a href="example2/function.cfg">function.cfg</a> -<LI> <a href="example2/gen.sh">gen.sh</a> -</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); - 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 - # 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) {...} - 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. - -<H3><a name="SecString">String handling</a></H3> - -Files: -<UL> -<LI> <a href="example3/function.h">function.h</a> -<LI> <a href="example3/function.cfg">function.cfg</a> -<LI> <a href="example3/gen.sh">gen.sh</a> -</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> <a href="example4/function.h">function.h</a> -<LI> <a href="example4/function.cfg">function.cfg</a> -<LI> <a href="example4/gen.sh">gen.sh</a> -</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 - # 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> <a href="example5/function.h">function.h</a> -<LI> <a href="example5/function.cfg">function.cfg</a> -<LI> <a href="example5/gen.sh">gen.sh</a> -</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 { - 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 - # 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 { - public static ScreenInfo create(); - public abstract ScreenInfo redBits(int val); - public abstract int redBits(); +</gluegen> + </pre> + + Please see the <a href="http://jogl.dev.java.net/">JOGL</a> and <a + href="http://joal.dev.java.net/">JOAL</a> build.xml files for + concrete, though non-trivial, examples of how to invoke GlueGen via + Ant. + + <h3><a name="SecPCPP">PCPP</a></h3> + + <p> + + GlueGen contains and uses a minimal C preprocessor called the "Pseudo + C Pre-Processor", or PCPP. A slightly specialized C preprocessor is + required for correct glue code generation with most libraries. + 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, and if the header is processed by a full C + preprocessor then the #define statements will be stripped become + unavailable for processing by the glue code generator. + + </p> + <p> + + PCPP is largely an invisible part of the glue code generation process; + however, it has certain limitations which make it difficult to parse + certain header files. First, it does not support macro evaluation in + any form, so if a header relies on macro evaluation in order to + generate code, PCPP will fail. It is possible that PCPP may fail + silently in this situation, causing GlueGen to simply not produce code + for the associated constructs. If GlueGen's output is not as expected + and there is heavy use of the C preprocessor in the header, run PCPP + against the header directly (PCPP takes simply the -I and filename + arguments accepted by GlueGen) and examine the output. + + </p> + <p> + + Second, PCPP contains only limited support for <code>#if</code> + clauses. Generally speaking, its handling of <code>#if defined(foo) || + defined(bar)</code> constructs is limited to approximately what is + required to handle the OpenGL header files. If the header being parsed + relies on moderately complicated expressions being evaluated by the C + preprocessor, check the output from PCPP and ensure it is as expected. + + </p> + <p> + + Contributions to PCPP would be especially welcome. It would be very + desirable to turn it into a full-blown C preprocessor with simply the + option of passing through #define statements unchanged. + + </p> + + <h3><a name="SecError">Error Reporting</a></h3> + + <p> + + Error reporting by GlueGen's parser is currently less than ideal. + Because PCPP makes <code>#include</code> directives disappear + completely with respect to the C parser (it appears that the + <code>#line</code> directives it emits are not being consumed properly + -- an area which needs more investigation), the line numbers reported + in parse failures are incorrect in all but the simplest cases. This + makes it difficult to determine in exactly what header file and on + exactly what construct the C parser failed. + + </p> + <p> + + Fortunately, there is a relatively simple workaround. PCPP can be run + with all of the same -I arguments passed to GlueGen and the result + piped to a new .c file. GlueGen can then be invoked on that .c file + (now containing no <code>#include</code> directives) and the line + numbers on any parse failures will be correct. + + </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) + 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 <a href="#SecPCPP">minimal 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; + 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="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="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="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 the <a href="#Implements">Implements</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="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="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="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 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 ); ... - } -</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> <a href="example6/function.cfg">function.cfg</a> -<LI> <a href="example6/gen.sh">gen.sh</a> -</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( - 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; - 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; -</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 -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 ???); -} -</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 - 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) { - 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, - 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 - # 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 -</PRE> - -<P> The final generated Java API is the following: </P> - -<PRE> - 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> <a href="example7/function.cfg">function.cfg</a> -<LI> <a href="example7/gen.sh">gen.sh</a> -</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; - - 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, - 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. + 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="#SecPCPP">PCPP</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 + 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.sun.gluegen.GlueGen \ + -I. -Ecom.sun.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); + 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 + # 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) {...} + 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 + # 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 { + 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 + # 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 { + 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( + 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; + 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; + </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 + 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 ???); + } + </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 + 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) { + 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, + 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 + # 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 + </pre> + + <p> The final generated Java API is the following: </p> + + <pre> + 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; + + 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, + 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 xmlns:dc="http://purl.org/dc/elements/1.1/" property="dc:title">JogAmp.org</span> - by <a xmlns:cc="http://creativecommons.org/ns#" href="http://jogamp.org" property="cc:attributionName" rel="cc:attributionURL">http://jogamp.org</a> + <span>JogAmp.org</span> + by <a href="http://jogamp.org">http://jogamp.org</a> is licensed under a <br/> - <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 License</a>. + <a href="http://creativecommons.org/licenses/by/3.0/us/">Creative Commons Attribution 3.0 License</a>. </div> </div> </div> |