From d0751a474e177b8bc4ca9f9d00968f670870075b Mon Sep 17 00:00:00 2001 From: Michael Zucchi Date: Tue, 23 Apr 2019 10:55:47 +0930 Subject: [PATCH] Added documentation for nativez-gen. nativez-gen now passes all unknown arguments to cproto. --- README | 137 ++++++++++++++++++++++++++++- src/notzed.nativez/jni/nativez-gen | 25 +++--- 2 files changed, 146 insertions(+), 16 deletions(-) diff --git a/README b/README index e73f60d..e361372 100644 --- a/README +++ b/README @@ -9,6 +9,10 @@ Introduction This is a C link library and Java base class which can be used to help implement libraries which use the Java Native Interface (JNI). +It provides a base class for native objects which provides automatic +(and manual) reclaimation, and a shared library for easy access to +these and other JNI utilities. + Compile ------- @@ -32,6 +36,7 @@ compilation, or non-modular use: `bin/notzed.nativez//include' - header files `bin/notzed.nativez//lib/libnativez.so' - linux shared library `bin/modules/notzed.nativez/' - compiled class files +`bin/notzed.nativez//bin/nativez-gen' - table generator Usage ----- @@ -57,13 +62,17 @@ directive. Native Library - - - - - - -- +Whilst not necessary one can use the native library for access to the +NativeZ_* functions and some other cross-platform tools. + The native library should link with -lnativez and include "nativez.h". Before using any functions invoke the nativez_OnLoad() function, typically in the native library's JNI_OnLoad() function. -Any instance of a class derived from NativeZ must be created using the -NativeZ_* functions. +Any instance of a class derived from NativeZ must be created or +referenced using the NativeZ_* functions in order to partake of +automatic cleanup. Native functions should take object arguments and resolve them to native pointers using NativeZ_getP(). @@ -71,12 +80,136 @@ native pointers using NativeZ_getP(). The nativez_* functions are just general JNI and useful cross-platform utility functions which may be freely used within (any) JNI code. +See nativez.h for more information. + +nativez-gen +-- - - - -- + +nativez provides a couple of functions for compact table based +resolution of shared library entry points from dynamically loaded +libraries, and for resolving Java classes and field and method +acccessors. + +Whilst the tables can be generated manually nativez-gen can be used to +generate correct tables from a definition file. When run on a +definition file it will create one or two pairs of static variables to +be included in the C file that uses it. + +nativez-gen requires `perl' and the header section processing requires +`cproto'. + +The definition file is made of any number of sections. Each section +starts with a header which must be on the same line (including the +`{') and a number of entries each on their own line followed by a `}'. +Non-EOL whitespace is ignored. No quoting or escaping is available. + +See also `src/notzed.nativez/jni/nativez.gen'. It's dumb but somewhat +messy perl. + +See also `src/notzed.nativez/jni/jni.make' for an example of how to +invoke it automatically. + +java section +- -- -- -- + +Each entry must be on a separate line as below. + +java VarName com/package/name/ClassName { + static funcName, funcSig + funcName, funcSig + static fieldName,fieldSig + fieldName,fieldSig +} + +VarName must be unique for each section in a single definition file. + +The *Name* and *Sig values are those passed to the corresponding JNI +functions. The static modifier calls the *Static* variaants. A +funcSig will contain a pair of parentheses and a fieldSig will not. + +For each java section the following definitions will be created: + +static struct { + jclass VarName_classid; + jmethodID funcName_[encodedSig]; + jmethodID funcName_[encodedSig]; + jfieldID fieldName_[encodedSig]; + jfieldID fieldName_[encodedSig]; +} java; + +static const char *java_names = + "#com/package/name/ClassName\0" + ":funcName\0funcSig\0" + ".funcName\0funcSig\0" + ";fieldName\0fieldSig\0" + ",fieldName\0fieldSig\0" + ; + +encodedSig depends on the arguments to nativez-gen. By default for +functions a compact variation of JNI name mangling is used where the +primitive types are lowercased and any object types are converted to +'l' with all [ collapsed to nothing. A longer option (--java-long) is +somewhat similar but not (current) quite the same as the JNI name +mangling and allows for overriden functions taking different object +types in the same position. + +See the nativez-gen header for the rest of the options. + +header section + -- -- -- -- + +A header section extracts prototypes from C .h header files and +creates a typesafe structure of same. + +header libname path/header.h { + funcname_a + funcmame_b +} + +libname is the name of the library as used in the +nativez_ResolveLibraries() table. i.e. it's just a key and not the +actual name. + +path/header.h should be the name as included directly in a C file, +i.e. it can be used direclty in a #include directive. It is relative +to the (-b path) command line argument. + +The contents of the section are just the function names required. + +All header sections in a definition file will be combined to create a +pair of variables. If one assumes a second section for libname2 is in +the file, this is an example output: + +#inclulde +#inclulde + +static struct { + /* libname */ + type (*funcname_a)(args); + type (*funcname_b)(args); + /* libname2 */ + type (*funcname_c)(args); +} fn; + +static const char *fn_names = + "#libname\0" + "funcname_a\0" + "funcname_b\0" + "@libname2\0" + "funcname_c\0" + ; + +See the nativez-gen header for the options. + LICENSE ------- This is supplied under the permissive 3-clause BSD license. It allows for commercial use. See also notzed.nativez/legal/LICENSE. +java.make is covered by the GNU GPL Version 3 or later but is only +required at build time. + Copyright (C) 2018,2019 Michael Zucchi Redistribution and use in source and binary forms, with or without diff --git a/src/notzed.nativez/jni/nativez-gen b/src/notzed.nativez/jni/nativez-gen index 2c7844c..ec47677 100755 --- a/src/notzed.nativez/jni/nativez-gen +++ b/src/notzed.nativez/jni/nativez-gen @@ -1,30 +1,27 @@ #!/usr/bin/perl # usage [ options ]* def-file.def -# -b basedir Base directory for any 'header' sections. -# -I incdir Extra include directory -# -Iincdir Extra include directory + +# -b basedir Base directory for any 'header' sections. It is added to the include path. # --func-name Function table variable name. Default is `fn'. # --java-name Java table variable name. Default is 'java'. # -J Create #defines to map java names to the variable name. # --java-long Create long java names for object types. Sort of like mangled jni names. +# All other options and arguments are passed to cproto. + $args = "$0 ".join " ", @ARGV; $java_name = "java"; $func_name = "fn"; $doJ = 0; $doLong = 0; +$cproto = ""; -while ($#ARGV >= 0) { +while ($#ARGV > 0) { my $cmd = shift; if ($cmd eq "-b") { $basedir = shift; - $includes.=" '-I${basedir}'"; - } elsif ($cmd eq "-I") { - my $dir = shift; - $includes.= " '-I$dir'"; - } elsif ($cmd =~ m/^-I/) { - $includes.= " '$cmd'"; + $cproto .= " -I '${basedir}'"; } elsif ($cmd eq "--func-name") { $func_name = shift; } elsif ($cmd eq "--java-name") { @@ -34,12 +31,12 @@ while ($#ARGV >= 0) { } elsif ($cmd eq "--java-long") { $doLong = 1; } else { - $def = $cmd; + $cproto .= " '$cmd'"; } } +$def = shift; -#die ("`$def': input file doesn't exist") if ! -f $def; -#die ("`$basedir': doesn't exist") if ! -d $basedir; +die ("`$def': input file doesn't exist") if ! -f $def; $header = ""; $librart = ""; @@ -62,7 +59,7 @@ while () { -f "$basedir/$header" || die ("header $header not found"); %proto = (); - open PROTO, "cproto -q -x ${includes} $basedir/$header|"; + open PROTO, "cproto -q -x ${cproto} $basedir/$header|"; while () { chop; -- 2.39.5