summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2023-06-20 04:02:12 +0200
committerSven Gothel <[email protected]>2023-06-20 04:02:12 +0200
commitb9dc722d689760bf85628edd8766dc6cd2360c8e (patch)
tree2d94b694cbc39b81f55ce1533da1f8d32e86ccaf /src
parentf7f554208c024280f1929df79bdbb83c758b8b49 (diff)
GlueGen Struct [15]: Add FunctionPointer getter and setter support w/ documentation
Diffstat (limited to 'src')
-rw-r--r--src/java/com/jogamp/gluegen/JavaEmitter.java123
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/generation/BindingJNILibLoader.java10
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/generation/Test2.java148
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/generation/test2.c59
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg30
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/generation/test2.h35
6 files changed, 319 insertions, 86 deletions
diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java
index c425c05..23aae96 100644
--- a/src/java/com/jogamp/gluegen/JavaEmitter.java
+++ b/src/java/com/jogamp/gluegen/JavaEmitter.java
@@ -965,10 +965,11 @@ public class JavaEmitter implements GlueEmitter {
final String fieldName = null==renamed ? field.getName() : renamed;
final String cfgFieldName1 = JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, fieldName);
if (fieldType.isFunctionPointer()) {
- // no offset/size for function pointer ..
if( GlueGen.debug() ) {
- System.err.printf("SE.os.%02d: %s / %s, %s (%s)%n", (i+1), field, cfgFieldName1, fieldType.getDebugString(), "SKIP FuncPtr");
+ System.err.printf("SE.os.%02d: %s / %s, %s (%s)%n", (i+1), field, cfgFieldName1, fieldType.getDebugString(), "FuncPtr");
}
+ generateOffsetAndSizeArrays(javaUnit, " ", fieldName, null, field, null); /* w/o size */
+ generateOffsetAndSizeArrays(javaUnit, "//", fieldName, fieldType, null, null);
} else if (fieldType.isCompound()) {
// FIXME: will need to support this at least in order to
// handle the union in jawt_Win32DrawingSurfaceInfo (fabricate
@@ -1099,6 +1100,28 @@ public class JavaEmitter implements GlueEmitter {
func.rename(renamed); // null is OK
generateFunctionPointerCode(methodBindingSet, javaUnit, jniUnit, structCTypeName,
containingCType, containingJType, i, func, fqStructFieldName1);
+ final String javaTypeName = "long";
+ final String capFieldName = capitalizeString(fieldName);
+ generateIsNullSignature(javaUnit, false, fieldName, fieldType, Ownership.Parent, capFieldName, false, false, null);
+ javaUnit.emitln(" {");
+ javaUnit.emitln(" return 0 == accessor.getLongAt(" + fieldName+"_offset[mdIdx], md.pointerSizeInBytes());");
+ javaUnit.emitln(" }");
+ javaUnit.emitln();
+ if( !immutableField && !fieldType.isConst() ) {
+ // Setter
+ generateSetterSignature(javaUnit, MethodAccess.PUBLIC, false, false, fieldName, fieldType, Ownership.Parent, containingJTypeName, capFieldName, null, javaTypeName, null, false, false, null, null, null);
+ javaUnit.emitln(" {");
+ javaUnit.emitln(" accessor.setLongAt(" + fieldName+"_offset[mdIdx], src, md.pointerSizeInBytes());");
+ javaUnit.emitln(" return this;");
+ javaUnit.emitln(" }");
+ javaUnit.emitln();
+ }
+ // Getter
+ generateGetterSignature(javaUnit, false, false, fieldName, fieldType, Ownership.Parent, javaTypeName, capFieldName, null, false, false, null, null);
+ javaUnit.emitln(" {");
+ javaUnit.emitln(" return accessor.getLongAt(" + fieldName+"_offset[mdIdx], md.pointerSizeInBytes());");
+ javaUnit.emitln(" }");
+ javaUnit.emitln();
} else if ( fieldType.isCompound() && !isOpaqueField ) {
// FIXME: will need to support this at least in order to
// handle the union in jawt_Win32DrawingSurfaceInfo (fabricate a name?)
@@ -1223,16 +1246,26 @@ public class JavaEmitter implements GlueEmitter {
final String fieldName, final Type fieldType, final Ownership ownership,
final boolean constElemCount, final boolean maxOneElem, final String elemCountExpr,
final boolean multiline, final boolean startNewPara) {
- final boolean isPointer;
+ final boolean isArray;
final Type referencedType;
+ final String relationship;
{
- final PointerType pointerType = fieldType.asPointer();
- if( null != pointerType ) {
- isPointer = true;
- referencedType = pointerType.getBaseType();
+ if( fieldType.isFunctionPointer() ) {
+ isArray = false;
+ referencedType = null;
+ relationship = "being";
+ } else if( fieldType.pointerDepth() > 0 ) {
+ isArray = true;
+ referencedType = fieldType.getBaseType();
+ relationship = "referencing";
+ } else if( fieldType.arrayDimension() > 0 ) {
+ isArray = true;
+ referencedType = null;
+ relationship = "being";
} else {
- isPointer = false;
+ isArray = false;
referencedType = null;
+ relationship = "being";
}
}
// isPointer = true;
@@ -1247,24 +1280,35 @@ public class JavaEmitter implements GlueEmitter {
}
final String ownershipTerm;
switch( ownership ) {
- case Parent: ownershipTerm = "an"; break;
+ case Parent: ownershipTerm = "a <i>struct</i> owned"; break;
case Java: ownershipTerm = "a <i>Java</i> owned"; break;
case Native: ownershipTerm = "a <i>natively</i> owned"; break;
default: ownershipTerm = "a <i>mixed and ambigously</i> owned (<b>warning</b>)"; break;
}
- final String relationship = isPointer ? "referencing" : "being";
-
- unit.emit("native field <code>"+fieldName+"</code>, "+relationship+" "+ownershipTerm+" array with "+(constElemCount?"fixed":"variable")+" element count");
- if( null != elemCountExpr ) {
- if( elemCountExpr.startsWith("get") && elemCountExpr.endsWith("()") ) {
- unit.emit(" of {@link #"+elemCountExpr+"} ");
- } else {
- unit.emit(" of <code>"+elemCountExpr+"</code> ");
- }
- if( constElemCount || Ownership.Mixed == ownership ) {
- unit.emit("elements.");
+ final String what;
+ if( fieldType.isFunctionPointer() ) {
+ what = "function pointer";
+ } else if( isArray ) {
+ what = "array";
+ } else {
+ what = fieldType.getClass().getSimpleName();
+ }
+ unit.emit("native field <code>"+fieldName+"</code>, "+relationship+" "+ownershipTerm+" "+what);
+ if( isArray ) {
+ unit.emit(" with "+(constElemCount?"fixed":"variable")+" element count");
+ if( null != elemCountExpr ) {
+ if( elemCountExpr.startsWith("get") && elemCountExpr.endsWith("()") ) {
+ unit.emit(" of {@link #"+elemCountExpr+"} ");
+ } else {
+ unit.emit(" of <code>"+elemCountExpr+"</code> ");
+ }
+ if( constElemCount || Ownership.Mixed == ownership ) {
+ unit.emit("elements.");
+ } else {
+ unit.emit("initial elements.");
+ }
} else {
- unit.emit("initial elements.");
+ unit.emit(".");
}
} else {
unit.emit(".");
@@ -1437,6 +1481,7 @@ public class JavaEmitter implements GlueEmitter {
false, // isPrivateNativeMethod
cfg);
emitter.addModifier(JavaMethodBindingEmitter.PUBLIC);
+ emitter.addModifier(JavaMethodBindingEmitter.FINAL);
emitter.emit();
javaUnit.emitln();
@@ -1572,17 +1617,17 @@ public class JavaEmitter implements GlueEmitter {
final JavaType containingJType,
final int i, final Field field, final String fieldName,
final boolean immutableAccess,
- final String returnSizeLookupName) throws Exception {
+ final String fqStructFieldName) throws Exception {
final Type fieldType = field.getType();
final JavaType javaType;
try {
javaType = typeToJavaType(fieldType, machDescJava);
} catch (final Exception e) {
throw new GlueGenException("Error occurred while creating array/pointer accessor for field \"" +
- returnSizeLookupName + "\", "+fieldType.getDebugString(), fieldType.getASTLocusTag(), e);
+ fqStructFieldName + "\", "+fieldType.getDebugString(), fieldType.getASTLocusTag(), e);
}
if( GlueGen.debug() ) {
- System.err.printf("SE.ac.%02d: fieldName %s%n", (i+1), fieldName);
+ System.err.printf("SE.ac.%02d: fieldName %s, fqName %s%n", (i+1), fieldName, fqStructFieldName);
System.err.printf("SE.ac.%02d: structCType %s, %s%n", (i+1), structCType.toString(), structCType.getSignature(null).toString());
System.err.printf("SE.ac.%02d: fieldType %s, %s%n", (i+1), fieldType.toString(), fieldType.getSignature(null).toString());
System.err.printf("SE.ac.%02d: javaType %s, %s%n", (i+1), javaType.toString(), javaType.getSignature(null).toString());
@@ -1593,8 +1638,8 @@ public class JavaEmitter implements GlueEmitter {
//
final String containingJTypeName = containingJType.getName();
final boolean isOpaque = isOpaque(fieldType);
- final boolean isStringOnly = cfg.returnsStringOnly(returnSizeLookupName); // exclude alternative ByteBuffer representation to String
- final boolean isString = isStringOnly || cfg.returnsString(returnSizeLookupName);
+ final boolean isStringOnly = cfg.returnsStringOnly(fqStructFieldName); // exclude alternative ByteBuffer representation to String
+ final boolean isString = isStringOnly || cfg.returnsString(fqStructFieldName);
if( isString ) {
unit.addTailCode(optStringCharsetCode);
}
@@ -1634,7 +1679,7 @@ public class JavaEmitter implements GlueEmitter {
if( null != arrayType ) {
final int[][] arrayLengthRes = new int[1][];
final boolean[] _useFixedArrayLen = { false };
- elemCountExpr = getArrayArrayLengthExpr(arrayType, returnSizeLookupName, _useFixedArrayLen, arrayLengthRes);
+ elemCountExpr = getArrayArrayLengthExpr(arrayType, fqStructFieldName, _useFixedArrayLen, arrayLengthRes);
// final int arrayLength = arrayLengthRes[0][0];
constElemCount = _useFixedArrayLen[0];
ownership = Ownership.Parent; // a fixed linear array
@@ -1644,11 +1689,11 @@ public class JavaEmitter implements GlueEmitter {
useGetCStringLength = false;
} else {
final PointerType pointerType = fieldType.asPointer();
- final String _elemCountExpr = cfg.returnedArrayLength(returnSizeLookupName);
+ final String _elemCountExpr = cfg.returnedArrayLength(fqStructFieldName);
baseCElemType = pointerType.getBaseType();
isPointer = true;
if( 1 != pointerType.pointerDepth() ) {
- final String msg = "SKIP ptr-ptr (depth "+pointerType.pointerDepth()+"): "+returnSizeLookupName +": "+fieldType;
+ final String msg = "SKIP ptr-ptr (depth "+pointerType.pointerDepth()+"): "+fqStructFieldName +": "+fieldType;
unit.emitln(" // "+msg);
unit.emitln();
LOG.log(WARNING, structCType.getASTLocusTag(), msg);
@@ -1702,13 +1747,13 @@ public class JavaEmitter implements GlueEmitter {
}
}
if( null == elemCountExpr ) {
- final String msg = "SKIP unsized array in struct: "+returnSizeLookupName+": "+fieldType.getSignature(null).toString();
+ final String msg = "SKIP unsized array in struct: "+fqStructFieldName+": "+fieldType.getSignature(null).toString();
unit.emitln(" // "+msg);
unit.emitln();
LOG.log(WARNING, structCType.getASTLocusTag(), msg);
return;
}
- boolean _maxOneElement = cfg.maxOneElement(returnSizeLookupName);
+ boolean _maxOneElement = cfg.maxOneElement(fqStructFieldName);
if( !_maxOneElement ) {
try {
_maxOneElement = 1 == Integer.parseInt(elemCountExpr);
@@ -1720,7 +1765,7 @@ public class JavaEmitter implements GlueEmitter {
}
if( !baseCElemType.hasSize() ) { // like 'void*' -> 'void'
- final String msg = "SKIP unsized field in struct: "+returnSizeLookupName+": fieldType "+fieldType.getSignature(null).toString()+", baseType "+baseCElemType.getSignature(null).toString();
+ final String msg = "SKIP unsized field in struct: "+fqStructFieldName+": fieldType "+fieldType.getSignature(null).toString()+", baseType "+baseCElemType.getSignature(null).toString();
unit.emitln(" // "+msg);
unit.emitln();
LOG.log(WARNING, structCType.getASTLocusTag(), msg);
@@ -1733,7 +1778,7 @@ public class JavaEmitter implements GlueEmitter {
baseJElemType = typeToJavaType(baseCElemType, machDescJava);
} catch (final Exception e ) {
throw new GlueGenException("Error occurred while creating array/pointer accessor for field \"" +
- returnSizeLookupName + "\", baseType "+baseCElemType.getDebugString()+", topType "+fieldType.getDebugString(),
+ fqStructFieldName + "\", baseType "+baseCElemType.getDebugString()+", topType "+fieldType.getDebugString(),
fieldType.getASTLocusTag(), e);
}
baseJElemTypeName = baseJElemType.getName();
@@ -1874,7 +1919,7 @@ public class JavaEmitter implements GlueEmitter {
if( isConstValue ) {
// constElemCount/Ownership.Native excluded: SKIP setter for constValue constElemCount Pointer w/ native ownership
if( Ownership.Native == ownership ) {
- throw new InternalError("Native ownership but adding potential memory-replacement for '"+returnSizeLookupName+"': "+fieldType.getSignature(null).toString());
+ throw new InternalError("Native ownership but adding potential memory-replacement for '"+fqStructFieldName+"': "+fieldType.getSignature(null).toString());
}
unit.emitln(" {");
unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+primElemSizeExpr+", 1);");
@@ -1971,7 +2016,7 @@ public class JavaEmitter implements GlueEmitter {
generateSetterSignature(unit, accessMod, false, false, fieldName, fieldType, ownership, containingJTypeName, capitalFieldName, null,
baseJElemTypeName+"[]", SetReplaceArrayArgsPost, constElemCount, maxOneElement, elemCountExpr, SetReplaceArrayApiDocDetail, SetReplaceArrayApiDocArgs);
if( Ownership.Native == ownership ) {
- throw new InternalError("Native ownership but adding potential memory-replacement for '"+returnSizeLookupName+"': "+fieldType.getSignature(null).toString());
+ throw new InternalError("Native ownership but adding potential memory-replacement for '"+fqStructFieldName+"': "+fieldType.getSignature(null).toString());
}
unit.emitln(" {");
unit.emitln(SetReplaceArrayArgsCheck);
@@ -2010,7 +2055,7 @@ public class JavaEmitter implements GlueEmitter {
generateSetterSignature(unit, accessMod, false, false, fieldName, fieldType, ownership, containingJTypeName, capitalFieldName, SetArrayArgsPre,
baseJElemTypeName+"[]", SetArrayArgsPost, constElemCount, maxOneElement, elemCountExpr, SetArrayApiDocDetail, SetArrayApiDocArgs);
if( Ownership.Native == ownership ) {
- throw new InternalError("Native ownership but adding potential memory-replacement for '"+returnSizeLookupName+"': "+fieldType.getSignature(null).toString());
+ throw new InternalError("Native ownership but adding potential memory-replacement for '"+fqStructFieldName+"': "+fieldType.getSignature(null).toString());
}
unit.emitln(" {");
unit.emitln(SetArrayArgsCheck);
@@ -2060,7 +2105,7 @@ public class JavaEmitter implements GlueEmitter {
if( isConstValue ) {
// constElemCount/Ownership.Native excluded: SKIP setter for constValue constElemCount Pointer w/ native ownership
if( Ownership.Native == ownership ) {
- throw new InternalError("Native ownership but adding potential memory-replacement for '"+returnSizeLookupName+"': "+fieldType.getSignature(null).toString());
+ throw new InternalError("Native ownership but adding potential memory-replacement for '"+fqStructFieldName+"': "+fieldType.getSignature(null).toString());
}
unit.emitln(" {");
unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+baseJElemTypeName+".size(), 1);");
@@ -2112,7 +2157,7 @@ public class JavaEmitter implements GlueEmitter {
generateSetterSignature(unit, accessMod, false, false, fieldName, fieldType, ownership, containingJTypeName, capitalFieldName, null,
baseJElemTypeName+"[]", SetReplaceArrayArgsPost, constElemCount, maxOneElement, elemCountExpr, SetReplaceArrayApiDocDetail, SetReplaceArrayApiDocArgs);
if( Ownership.Native == ownership ) {
- throw new InternalError("Native ownership but adding potential memory-replacement for '"+returnSizeLookupName+"': "+fieldType.getSignature(null).toString());
+ throw new InternalError("Native ownership but adding potential memory-replacement for '"+fqStructFieldName+"': "+fieldType.getSignature(null).toString());
}
unit.emitln(" {");
unit.emitln(SetReplaceArrayArgsCheck);
@@ -2147,7 +2192,7 @@ public class JavaEmitter implements GlueEmitter {
generateSetterSignature(unit, accessMod, false, false, fieldName, fieldType, ownership, containingJTypeName, capitalFieldName, SetArrayArgsPre,
baseJElemTypeName+"[]", SetArrayArgsPost, constElemCount, maxOneElement, elemCountExpr, SetArrayApiDocDetail, SetArrayApiDocArgs);
if( Ownership.Native == ownership ) {
- throw new InternalError("Native ownership but adding potential memory-replacement for '"+returnSizeLookupName+"': "+fieldType.getSignature(null).toString());
+ throw new InternalError("Native ownership but adding potential memory-replacement for '"+fqStructFieldName+"': "+fieldType.getSignature(null).toString());
}
unit.emitln(" {");
unit.emitln(SetArrayArgsCheck);
diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/BindingJNILibLoader.java b/src/junit/com/jogamp/gluegen/test/junit/generation/BindingJNILibLoader.java
index 6b841ad..67f4918 100644
--- a/src/junit/com/jogamp/gluegen/test/junit/generation/BindingJNILibLoader.java
+++ b/src/junit/com/jogamp/gluegen/test/junit/generation/BindingJNILibLoader.java
@@ -54,6 +54,16 @@ public class BindingJNILibLoader extends JNILibLoaderBase {
}
});
}
+
+ public static void loadBindingtest2() {
+ SecurityUtil.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
+ public Object run() {
+ loadLibrary("Bindingtest2", null, true, BindingJNILibLoader.class.getClassLoader());
+ return null;
+ }
+ });
+ }
}
diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/Test2.java b/src/junit/com/jogamp/gluegen/test/junit/generation/Test2.java
new file mode 100644
index 0000000..636eea7
--- /dev/null
+++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test2.java
@@ -0,0 +1,148 @@
+/**
+ * Copyright 2023 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.gluegen.test.junit.generation;
+
+import java.io.IOException;
+
+import com.jogamp.gluegen.test.junit.generation.impl.Bindingtest2Impl;
+import com.jogamp.common.os.NativeLibrary;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import org.junit.FixMethodOrder;
+import org.junit.runners.MethodSorters;
+
+/**
+ * Test {@link Bindingtest2} with {@link T2_InitializeOptions} instance and function pointer...
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class Test2 extends BaseClass {
+
+ static NativeLibrary dynamicLookupHelper;
+
+ /**
+ * Verifies loading of the new library.
+ */
+ @BeforeClass
+ public static void chapter__TestLoadLibrary() throws Exception {
+ BindingJNILibLoader.loadBindingtest2();
+ dynamicLookupHelper = NativeLibrary.open("test2", false, false, Test2.class.getClassLoader(), true);
+ Assert.assertNotNull("NativeLibrary.open(test2) failed", dynamicLookupHelper);
+
+ Bindingtest2Impl.resetProcAddressTable(dynamicLookupHelper);
+ }
+
+ /**
+ * Verifies unloading of the new library.
+ */
+ @AfterClass
+ public static void chapter0XTestUnloadLibrary() throws Exception {
+ Assert.assertNotNull(dynamicLookupHelper);
+ dynamicLookupHelper.close();
+ dynamicLookupHelper = null;
+ }
+
+ /**
+ * Test Bindingtest2 with T2_InitializeOptions instance and function pointer
+ */
+ @Test
+ public void chapter01() throws Exception {
+ final Bindingtest2 bt2 = new Bindingtest2Impl();
+
+ final T2_InitializeOptions options = T2_InitializeOptions.create();
+ Assert.assertEquals(true, options.isOverrideThreadAffinityNull());
+ Assert.assertEquals(true, options.isProductNameNull());
+ Assert.assertEquals(true, options.isProductVersionNull());
+ Assert.assertEquals(true, options.isCustomFuncA1Null());
+ Assert.assertEquals(true, options.isCustomFuncA2Null());
+ Assert.assertEquals(true, options.isCustomFuncB1Null());
+ Assert.assertEquals(true, options.isCustomFuncB2Null());
+
+ bt2.Initialize(options);
+ Assert.assertEquals(true, options.isOverrideThreadAffinityNull());
+ Assert.assertEquals(false, options.isProductNameNull());
+ Assert.assertEquals(false, options.isProductVersionNull());
+ Assert.assertEquals(false, options.isCustomFuncA1Null());
+ Assert.assertEquals(false, options.isCustomFuncA2Null());
+ Assert.assertEquals(false, options.isCustomFuncB1Null());
+ Assert.assertEquals(false, options.isCustomFuncB2Null());
+ Assert.assertEquals(false, options.isCustomFuncA1Null());
+ Assert.assertEquals(1, options.getApiVersion());
+ Assert.assertEquals("Product Name", options.getProductName());
+ Assert.assertEquals("Product Version", options.getProductVersion());
+ Assert.assertEquals(0xa001, options.CustomFuncA1(0));
+ Assert.assertEquals(0xa002, options.CustomFuncA2(0));
+ final T2_UserData ud1 = T2_UserData.create();
+ {
+ ud1.setBalance(101);
+ ud1.setName("John Doe");
+ Assert.assertEquals(101, ud1.getBalance());
+ Assert.assertEquals("John Doe", ud1.getName());
+ }
+ final T2_UserData ud2 = T2_UserData.create();
+ {
+ ud2.setBalance(404);
+ ud2.setName("Jane Doe");
+ Assert.assertEquals(404, ud2.getBalance());
+ Assert.assertEquals("Jane Doe", ud2.getName());
+ }
+ Assert.assertEquals(101, options.CustomFuncB1(ud1));
+ Assert.assertEquals(404, options.CustomFuncB1(ud2));
+ Assert.assertEquals(-101, options.CustomFuncB2(ud1));
+ Assert.assertEquals(-404, options.CustomFuncB2(ud2));
+ // switch functions
+ {
+ final long funcB1 = options.getCustomFuncB1();
+ final long funcB2 = options.getCustomFuncB2();
+ options.setCustomFuncB1(funcB2);
+ options.setCustomFuncB2(funcB1);
+ }
+ Assert.assertEquals(-101, options.CustomFuncB1(ud1));
+ Assert.assertEquals(-404, options.CustomFuncB1(ud2));
+ Assert.assertEquals(101, options.CustomFuncB2(ud1));
+ Assert.assertEquals(404, options.CustomFuncB2(ud2));
+
+ bt2.Release(options);
+ Assert.assertEquals(true, options.isOverrideThreadAffinityNull());
+ Assert.assertEquals(true, options.isProductNameNull());
+ Assert.assertEquals(true, options.isProductVersionNull());
+ Assert.assertEquals(true, options.isCustomFuncA1Null());
+ Assert.assertEquals(true, options.isCustomFuncA2Null());
+ Assert.assertEquals(true, options.isCustomFuncB1Null());
+ Assert.assertEquals(true, options.isCustomFuncB2Null());
+ }
+
+ public static void main(final String args[]) throws IOException {
+ final String tstname = Test2.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+}
diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.c b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.c
index 3fff02c..561b3ae 100644
--- a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.c
+++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.c
@@ -1,20 +1,55 @@
#include "test2.h"
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
-int Initialize(const T2_InitializeOptions* Options) {
- fprintf(stderr, "T2 Initialize API 0x%X, product %s, version %s\n",
- Options->ApiVersion,
- Options->ProductName,
- Options->ProductVersion);
- fprintf(stderr, "- MemFuncs: alloc %p, realloc %p, release %p\n",
- Options->AllocateMemoryFunction,
- Options->ReallocateMemoryFunction,
- Options->ReleaseMemoryFunction);
- return 0;
+static int32_t CustomFuncA1(void* aptr) {
+ (void)aptr;
+ return 0xa001;
+}
+static int32_t CustomFuncA2(void* aptr) {
+ (void)aptr;
+ return 0xa002;
+}
+
+static int32_t CustomFuncB1(T2_UserData* pUserData) {
+ return pUserData->balance;
}
-int Shutdown() {
- return 0;
+static int32_t CustomFuncB2(T2_UserData* pUserData) {
+ return -pUserData->balance;
}
+int Initialize(T2_InitializeOptions* Options) {
+ Options->ProductName = calloc(100, sizeof(char));
+ Options->ProductVersion = calloc(100, sizeof(char));
+ strncpy(Options->ProductName, "Product Name", 100);
+ strncpy(Options->ProductVersion, "Product Version", 100);
+ Options->ApiVersion = 1;
+
+ Options->Reserved1 = NULL;
+ Options->CustomFuncA1 = CustomFuncA1;
+ Options->CustomFuncA2 = CustomFuncA2;
+ Options->CustomFuncB1 = CustomFuncB1;
+ Options->CustomFuncB2 = CustomFuncB2;
+
+ Options->OverrideThreadAffinity = NULL;
+}
+
+int Release(T2_InitializeOptions* Options) {
+ if( NULL != Options->ProductName ) {
+ free( Options->ProductName );
+ Options->ProductName = NULL;
+ }
+ if( NULL != Options->ProductVersion ) {
+ free( Options->ProductVersion );
+ Options->ProductVersion = NULL;
+ }
+ Options->CustomFuncA1 = NULL;
+ Options->CustomFuncA2 = NULL;
+ Options->CustomFuncB1 = NULL;
+ Options->CustomFuncB2 = NULL;
+}
+
+
diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg
index b55e1d6..4ca9ae5 100644
--- a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg
+++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg
@@ -1,12 +1,12 @@
Package com.jogamp.gluegen.test.junit.generation
-JavaClass BindingtestT2
+JavaClass Bindingtest2
Style InterfaceAndImpl
JavaOutputDir classes
NativeOutputDir native
# Use a ProcAddressTable so we dynamically look up the routines
EmitProcAddressTable true
-ProcAddressTableClassName BindingtestT2ProcAddressTable
+ProcAddressTableClassName Bindingtest2ProcAddressTable
GetProcAddressTableExpr _table
ProcAddressNameExpr PFN $UPPERCASE({0}) PROC
@@ -19,36 +19,32 @@ ForceProcAddressGen __ALL__
# pointer typedefs for these routines to MYAPIENTRY
# LocalProcAddressCallingConvention __ALL__ MYAPIENTRY
-Opaque long T2_AllocateMemoryFunc
-Opaque long T2_ReallocateMemoryFunc
-Opaque long T2_ReleaseMemoryFunc
+Opaque long void*
EmitStruct T2_ThreadAffinity
StructPackage T2_ThreadAffinity com.jogamp.gluegen.test.junit.generation
+EmitStruct T2_UserData
+StructPackage T2_UserData com.jogamp.gluegen.test.junit.generation
+ReturnsStringOnly T2_UserData.name
+
EmitStruct T2_InitializeOptions
StructPackage T2_InitializeOptions com.jogamp.gluegen.test.junit.generation
ReturnsStringOnly T2_InitializeOptions.ProductName
ReturnsStringOnly T2_InitializeOptions.ProductVersion
-Opaque long T2_InitializeOptions.Reserved2
-# ImmutableAccess long T2_InitializeOptions.Reserved
-
# ReturnedArrayLength T2_InitializeOptions.OverrideThreadAffinity 1
MaxOneElement T2_InitializeOptions.OverrideThreadAffinity
-ReturnsOpaque long T2_InitializeOptions.AllocateMemoryFunction
-ReturnsOpaque long T2_InitializeOptions.ReallocateMemoryFunc
-ReturnsOpaque long T2_InitializeOptions.ReleaseMemoryFunc
-
CustomCCode #include "test2.h"
-Import com.jogamp.gluegen.test.junit.generation.BindingtestT2
+Import com.jogamp.gluegen.test.junit.generation.Bindingtest2
Import com.jogamp.gluegen.test.junit.generation.T2_InitializeOptions
Import com.jogamp.gluegen.test.junit.generation.T2_ThreadAffinity
+Import com.jogamp.gluegen.test.junit.generation.T2_UserData
-CustomJavaCode BindingtestT2Impl private static BindingtestT2ProcAddressTable _table = new BindingtestT2ProcAddressTable();
-CustomJavaCode BindingtestT2Impl public static void resetProcAddressTable(DynamicLookupHelper lookup) {
-CustomJavaCode BindingtestT2Impl _table.reset(lookup);
-CustomJavaCode BindingtestT2Impl }
+CustomJavaCode Bindingtest2Impl private static Bindingtest2ProcAddressTable _table = new Bindingtest2ProcAddressTable();
+CustomJavaCode Bindingtest2Impl public static void resetProcAddressTable(DynamicLookupHelper lookup) {
+CustomJavaCode Bindingtest2Impl _table.reset(lookup);
+CustomJavaCode Bindingtest2Impl }
diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h
index 58b5c8f..0fca16a 100644
--- a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h
+++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h
@@ -2,14 +2,6 @@
#include <gluegen_stdint.h>
#include <gluegen_stddef.h>
-typedef void* ( * T2_AllocateMemoryFunc)(size_t SizeInBytes, size_t Alignment);
-
-typedef void* ( * T2_ReallocateMemoryFunc)(void* Pointer, size_t SizeInBytes, size_t Alignment);
-
-typedef void ( * T2_ReleaseMemoryFunc)(void* Pointer);
-
-typedef void ( * T2_CustomFunc)(void* Pointer);
-
typedef struct {
int32_t ApiVersion;
uint64_t NetworkWork;
@@ -21,21 +13,28 @@ typedef struct {
} T2_ThreadAffinity;
typedef struct {
- int32_t ApiVersion;
- T2_AllocateMemoryFunc AllocateMemoryFunction;
- T2_ReallocateMemoryFunc ReallocateMemoryFunction;
- T2_ReleaseMemoryFunc ReleaseMemoryFunction;
-
+ int32_t balance;
+ const char* name;
+} T2_UserData;
+
+typedef int32_t ( * T2_CustomFuncA)(void* aptr);
+
+typedef int32_t ( * T2_CustomFuncB)(T2_UserData* pUserData);
+
+typedef struct {
const char* ProductName;
-
const char* ProductVersion;
+ int32_t ApiVersion;
+
void* Reserved1;
- void* Reserved2;
- T2_CustomFunc CustomFunc2;
+ T2_CustomFuncA CustomFuncA1;
+ T2_CustomFuncA CustomFuncA2;
+ T2_CustomFuncB CustomFuncB1;
+ T2_CustomFuncB CustomFuncB2;
T2_ThreadAffinity* OverrideThreadAffinity;
} T2_InitializeOptions;
-extern int Initialize(const T2_InitializeOptions* Options);
-extern int Shutdown();
+extern int Initialize(T2_InitializeOptions* Options);
+extern int Release(T2_InitializeOptions* Options);