More Java nivision wrapper fixes.

- Fix sliceByteBuffer, getBytes, and putBytes implementations, which had
  functional errors.  Also, getBytes and putBytes now use the ByteBuffer
  get/put byte[] functions, which should improve performance.

- Don't generate wrappers for functions that are not available in the
  shared library.

Change-Id: Iaf45814b34720d3fdcd58adf99ad9c3ff2703bc3
This commit is contained in:
Peter Johnson
2015-01-14 23:49:37 -08:00
parent 9fda920055
commit d0258923e8
6 changed files with 81 additions and 2792 deletions

2
.gitignore vendored
View File

@@ -15,6 +15,8 @@ wpilibj/wpilibJavaJNI/nivision/*.cpp
wpilibj/wpilibJavaJNI/nivision/*.s
wpilibj/wpilibJavaJNI/nivision/*_arm.ini
wpilibj/wpilibJavaJNI/nivision/*.java
wpilibj/wpilibJavaJNI/nivision/nivision_funcs.txt
wpilibj/wpilibJavaJNI/nivision/imaqdx_funcs.txt
# Created by the jenkins test script
test-reports

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
IMAQdxGetAttributeU32
IMAQdxGetAttributeI64
IMAQdxGetAttributeF64
IMAQdxGetAttributeString
IMAQdxGetAttributeEnum
IMAQdxGetAttributeBool
IMAQdxGetAttributeMinimumU32
IMAQdxGetAttributeMinimumI64
IMAQdxGetAttributeMinimumF64
IMAQdxGetAttributeMaximumU32
IMAQdxGetAttributeMaximumI64
IMAQdxGetAttributeMaximumF64
IMAQdxGetAttributeIncrementU32
IMAQdxGetAttributeIncrementI64
IMAQdxGetAttributeIncrementF64
IMAQdxSetAttributeU32
IMAQdxSetAttributeI64
IMAQdxSetAttributeF64
IMAQdxSetAttributeString
IMAQdxSetAttributeEnum
IMAQdxSetAttributeBool

View File

@@ -843,10 +843,11 @@ for (int i=0, off={foffset}; i<%s; i++, off += {struct_sz})
class JavaEmitter:
def __init__(self, outdir, config, config_struct):
def __init__(self, outdir, config, config_struct, library_funcs):
self.outdir = outdir
self.config = config
self.config_struct = config_struct
self.library_funcs = library_funcs
self.package = "com.ni.vision"
self.classname = "NIVision"
self.classpath = self.package.replace(".", "/") + "/" + self.classname
@@ -930,21 +931,29 @@ public class {classname} {{
}}
public static ByteBuffer sliceByteBuffer(ByteBuffer bb, int offset, int size) {{
ByteBuffer new_bb = bb.duplicate().order(ByteOrder.nativeOrder());
new_bb.position(offset);
new_bb.limit(size);
int pos = bb.position();
int lim = bb.limit();
bb.position(offset);
bb.limit(offset+size);
ByteBuffer new_bb = bb.slice().order(ByteOrder.nativeOrder());
bb.position(pos);
bb.limit(lim);
return new_bb;
}}
public static ByteBuffer getBytes(ByteBuffer bb, byte[] dst, int offset, int size) {{
for (int i=offset; i<offset+size; i++)
dst[i] = bb.get(i);
int pos = bb.position();
bb.position(offset);
bb.get(dst, 0, size);
bb.position(pos);
return bb;
}}
public static ByteBuffer putBytes(ByteBuffer bb, byte[] src, int offset, int size) {{
for (int i=offset; i<offset+size; i++)
bb.put(i, src[i]);
int pos = bb.position();
bb.position(offset);
bb.put(src, 0, size);
bb.position(pos);
return bb;
}}
@@ -1462,6 +1471,8 @@ static const char* getErrorText(int err) {{
raise NotImplementedError("typedef function not implemented")
def function(self, name, restype, params):
if name not in self.library_funcs:
return
if name == "IMAQdxEnumerateVideoModes":
# full custom code
print("""
@@ -1921,7 +1932,7 @@ JNIEXPORT {rettype} JNICALL Java_{package}_{classname}__1{name}({args})
def generate(srcdir, outdir, inputs):
emit = None
for fname, config_struct_path, configpath in inputs:
for fname, config_struct_path, configpath, funcs_path in inputs:
# read config files
config_struct = configparser.ConfigParser()
config_struct.read(config_struct_path)
@@ -1930,6 +1941,11 @@ def generate(srcdir, outdir, inputs):
block_comment_exclude = set(x.strip() for x in
config.get("Block Comment", "exclude").splitlines())
library_funcs = set()
with open(funcs_path) as ff:
for line in ff:
library_funcs.add(line.strip())
# open input file
with open(fname) as inf:
# prescan for undefined structures
@@ -1937,10 +1953,11 @@ def generate(srcdir, outdir, inputs):
inf.seek(0)
if emit is None:
emit = JavaEmitter(outdir, config, config_struct)
emit = JavaEmitter(outdir, config, config_struct, library_funcs)
else:
emit.config = config
emit.config_struct = config_struct
emit.library_funcs = library_funcs
# generate
parse_file(emit, inf, block_comment_exclude)
@@ -1948,15 +1965,16 @@ def generate(srcdir, outdir, inputs):
emit.finish()
if __name__ == "__main__":
if len(sys.argv) < 4 or ((len(sys.argv)-1) % 3) != 0:
print("Usage: gen_wrap.py <header.h config_struct.ini config.ini>...")
if len(sys.argv) < 5 or ((len(sys.argv)-1) % 4) != 0:
print("Usage: gen_wrap.py <header.h config_struct.ini config.ini funcs.txt>...")
exit(0)
inputs = []
for i in range(1, len(sys.argv), 3):
for i in range(1, len(sys.argv), 4):
fname = sys.argv[i]
config_struct_name = sys.argv[i+1]
configname = sys.argv[i+2]
inputs.append((fname, config_struct_name, configname))
funcs_name = sys.argv[i+3]
inputs.append((fname, config_struct_name, configname, funcs_name))
generate("", "", inputs)

View File

@@ -13,18 +13,28 @@ python gen_struct_sizer.py ../../../wpilibc/wpilibC++Devices/include/NIIMAQdx.h
arm-frc-linux-gnueabi-gcc -I../../../wpilibc/wpilibC++Devices/include -S struct_sizer.c
cat struct_sizer.s | python get_struct_size.py > imaqdx_arm.ini
# Get functions actually in the .so; some functions are in the header but
# not the shared library!
arm-frc-linux-gnueabi-nm -D ../../../ni-libraries/libnivision.so.14.0.0 | cut -c 12- | grep ^imaq > nivision_funcs.txt
echo Priv_ReadJPEGString_C >> nivision_funcs.txt
arm-frc-linux-gnueabi-nm -D ../../../ni-libraries/libniimaqdx.so.14.0.0 | cut -c 12- | grep ^IMAQdx > imaqdx_funcs.txt
# Run python generator.
python gen_java.py \
../../../wpilibc/wpilibC++Devices/include/nivision.h \
nivision_arm.ini \
nivision_2011.ini \
nivision_funcs.txt \
\
../../../wpilibc/wpilibC++Devices/include/NIIMAQdx.h \
imaqdx_arm.ini \
imaqdx.ini \
imaqdx_funcs.txt \
\
dxattr.h \
imaqdx_arm.ini \
dxattr.ini
dxattr.ini \
dxattr_funcs.txt
# Stick generated files into appropriate places.
cp NIVision.cpp ../lib/NIVisionJNI.cpp