From b9dc722d689760bf85628edd8766dc6cd2360c8e Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Tue, 20 Jun 2023 04:02:12 +0200 Subject: GlueGen Struct [15]: Add FunctionPointer getter and setter support w/ documentation --- .../test/junit/generation/BindingJNILibLoader.java | 10 ++ .../gluegen/test/junit/generation/Test2.java | 148 +++++++++++++++++++++ .../jogamp/gluegen/test/junit/generation/test2.c | 59 ++++++-- .../jogamp/gluegen/test/junit/generation/test2.cfg | 30 ++--- .../jogamp/gluegen/test/junit/generation/test2.h | 35 +++-- 5 files changed, 235 insertions(+), 47 deletions(-) create mode 100644 src/junit/com/jogamp/gluegen/test/junit/generation/Test2.java (limited to 'src/junit/com/jogamp/gluegen') 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() { + @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 +#include +#include -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 #include -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); -- cgit v1.2.3