From 65e9c14e1566d5bfa88435d460c699c2a8fd23b7 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Tue, 20 Jun 2023 11:24:12 +0200 Subject: GlueGen Struct [15b]: FunctionPointer: Drop isNull() -> use get() --- doc/GlueGen_Mapping.html | 60 +++++----------------- doc/GlueGen_Mapping.md | 55 +++++--------------- src/java/com/jogamp/gluegen/JavaEmitter.java | 9 +--- .../gluegen/test/junit/generation/Test2.java | 25 +++++---- .../jogamp/gluegen/test/junit/generation/test2.c | 12 ++--- .../jogamp/gluegen/test/junit/generation/test2.h | 2 +- 6 files changed, 47 insertions(+), 116 deletions(-) diff --git a/doc/GlueGen_Mapping.html b/doc/GlueGen_Mapping.html index d3f7aef..69aa11f 100644 --- a/doc/GlueGen_Mapping.html +++ b/doc/GlueGen_Mapping.html @@ -1689,10 +1689,9 @@ IndexOutOfBoundsException is thrown

Struct Function Pointer Support

GlueGen supports function pointers as struct fields,
-generating function calls as methods as well as -is<FuncName>Null() checks
-and function pointer opaque getter and setter as long -types.

+generating function calls as methods as well function-pointer opaque +getter and setter as long types.
+The latter only in case if mutable, i.e. non-const.

Example

Assume the following C Header file example:

typedef struct {
@@ -1704,7 +1703,7 @@ typedef int32_t ( * T2_CustomFuncA)(void* aptr);
 typedef int32_t ( * T2_CustomFuncB)(T2_UserData* pUserData);
 
 typedef struct {
-    T2_CustomFuncA CustomFuncA1;
+    const T2_CustomFuncA CustomFuncA1;
     T2_CustomFuncB CustomFuncB1;
 } T2_InitializeOptions;

and the following GlueGen no-magic configuration

@@ -1716,52 +1715,19 @@ StructPackage T2_UserData com.jogamp.gluegen.test.junit.generation EmitStruct T2_InitializeOptions StructPackage T2_InitializeOptions com.jogamp.gluegen.test.junit.generation

This will lead to the following result for -T2_InitializeOptions.customFuncA1

-
  /** Interface to C language function: <br> <code>int32_t CustomFuncA1(void *  aptr)</code><br>   */
-  public final int CustomFuncA1(long aptr)  { ... }
-  
-  /**
-   * Returns `true` if native pointer <code>CustomFuncA1</code> is `null`, otherwise `false`.
-   * <p>
-   * Corresponds to native field <code>CustomFuncA1</code>, being a <i>struct</i> owned function pointer.
-   * </p>
-   * <p>
-   * Native Field Signature <code>(PointerType) typedef 'T2_CustomFuncA' -> int32_t (*)(void *  aptr), size [fixed false, lnx64 8], const[false], pointer*1, funcPointer</code>
-   * </p>
-   */
-  public final boolean isCustomFuncA1Null() { .. }
-
-  /**
-   * Setter for native field <code>CustomFuncA1</code>, being a <i>struct</i> owned function pointer.
-   * <p>
-   * Native Field Signature <code>(PointerType) typedef 'T2_CustomFuncA' -> int32_t (*)(void *  aptr), size [fixed false, lnx64 8], const[false], pointer*1, funcPointer</code>
-   * </p>
-   */
-  public final T2_InitializeOptions setCustomFuncA1(long src) { .. }
-
-  /**
+const T2_CustomFuncA customFuncA1

+
  /**
    * Getter for native field <code>CustomFuncA1</code>, being a <i>struct</i> owned function pointer.
    * <p>
    * Native Field Signature <code>(PointerType) typedef 'T2_CustomFuncA' -> int32_t (*)(void *  aptr), size [fixed false, lnx64 8], const[false], pointer*1, funcPointer</code>
    * </p>
    */
-  public final long getCustomFuncA1() { .. }    
-

and similar to T2_InitializeOptions.customFuncB1

-
  /** Interface to C language function: <br> <code>int32_t CustomFuncB1(T2_UserData *  pUserData)</code><br>   */
-  public final int CustomFuncB1(T2_UserData pUserData)  { .. }
+  public final long getCustomFuncA1() { .. }
   
-  /**
-   * Returns `true` if native pointer <code>CustomFuncB1</code> is `null`, otherwise `false`.
-   * <p>
-   * Corresponds to native field <code>CustomFuncB1</code>, being a <i>struct</i> owned function pointer.
-   * </p>
-   * <p>
-   * Native Field Signature <code>(PointerType) typedef 'T2_CustomFuncB' -> int32_t (*)(T2_UserData *  pUserData), size [fixed false, lnx64 8], const[false], pointer*1, funcPointer</code>
-   * </p>
-   */
-  public final boolean isCustomFuncB1Null() { .. }
-
-  /**
+  /** Interface to C language function: <br> <code>int32_t CustomFuncA1(void *  aptr)</code><br>   */
+  public final int CustomFuncA1(long aptr)  { ... }  
+

and similar to T2_CustomFuncB customFuncB1

+
  /**
    * Setter for native field <code>CustomFuncB1</code>, being a <i>struct</i> owned function pointer.
    * <p>
    * Native Field Signature <code>(PointerType) typedef 'T2_CustomFuncB' -> int32_t (*)(T2_UserData *  pUserData), size [fixed false, lnx64 8], const[false], pointer*1, funcPointer</code>
@@ -1776,7 +1742,9 @@ StructPackage T2_InitializeOptions com.jogamp.gluegen.test.junit.generation
+ + /** Interface to C language function: <br> <code>int32_t CustomFuncB1(T2_UserData * pUserData)</code><br> */ + public final int CustomFuncB1(T2_UserData pUserData) { .. }

Platform Header Files

GlueGen provides convenient platform headers,
which can be included in your C header files for native compilation and diff --git a/doc/GlueGen_Mapping.md b/doc/GlueGen_Mapping.md index 9b562ee..87124e7 100644 --- a/doc/GlueGen_Mapping.md +++ b/doc/GlueGen_Mapping.md @@ -539,8 +539,8 @@ A similar mapping is produced for `struct` types, i.e. *compounds*. ### Struct Function Pointer Support GlueGen supports function pointers as struct fields, -generating function calls as methods as well as `isNull()` checks -and function pointer opaque getter and setter as `long` types. +generating function calls as methods as well function-pointer opaque getter and setter as `long` types. +The latter only in case if mutable, i.e. non-const. #### Example Assume the following C Header file example: @@ -554,7 +554,7 @@ typedef int32_t ( * T2_CustomFuncA)(void* aptr); typedef int32_t ( * T2_CustomFuncB)(T2_UserData* pUserData); typedef struct { - T2_CustomFuncA CustomFuncA1; + const T2_CustomFuncA CustomFuncA1; T2_CustomFuncB CustomFuncB1; } T2_InitializeOptions; ``` @@ -570,55 +570,22 @@ EmitStruct T2_InitializeOptions StructPackage T2_InitializeOptions com.jogamp.gluegen.test.junit.generation ``` -This will lead to the following result for `T2_InitializeOptions.customFuncA1` +This will lead to the following result for `const T2_CustomFuncA customFuncA1` ``` - /** Interface to C language function:
int32_t CustomFuncA1(void * aptr)
*/ - public final int CustomFuncA1(long aptr) { ... } - - /** - * Returns `true` if native pointer CustomFuncA1 is `null`, otherwise `false`. - *

- * Corresponds to native field CustomFuncA1, being a struct owned function pointer. - *

- *

- * Native Field Signature (PointerType) typedef 'T2_CustomFuncA' -> int32_t (*)(void * aptr), size [fixed false, lnx64 8], const[false], pointer*1, funcPointer - *

- */ - public final boolean isCustomFuncA1Null() { .. } - - /** - * Setter for native field CustomFuncA1, being a struct owned function pointer. - *

- * Native Field Signature (PointerType) typedef 'T2_CustomFuncA' -> int32_t (*)(void * aptr), size [fixed false, lnx64 8], const[false], pointer*1, funcPointer - *

- */ - public final T2_InitializeOptions setCustomFuncA1(long src) { .. } - /** * Getter for native field CustomFuncA1, being a struct owned function pointer. *

* Native Field Signature (PointerType) typedef 'T2_CustomFuncA' -> int32_t (*)(void * aptr), size [fixed false, lnx64 8], const[false], pointer*1, funcPointer *

*/ - public final long getCustomFuncA1() { .. } + public final long getCustomFuncA1() { .. } + + /** Interface to C language function:
int32_t CustomFuncA1(void * aptr)
*/ + public final int CustomFuncA1(long aptr) { ... } ``` -and similar to `T2_InitializeOptions.customFuncB1` +and similar to `T2_CustomFuncB customFuncB1` ``` - /** Interface to C language function:
int32_t CustomFuncB1(T2_UserData * pUserData)
*/ - public final int CustomFuncB1(T2_UserData pUserData) { .. } - - /** - * Returns `true` if native pointer CustomFuncB1 is `null`, otherwise `false`. - *

- * Corresponds to native field CustomFuncB1, being a struct owned function pointer. - *

- *

- * Native Field Signature (PointerType) typedef 'T2_CustomFuncB' -> int32_t (*)(T2_UserData * pUserData), size [fixed false, lnx64 8], const[false], pointer*1, funcPointer - *

- */ - public final boolean isCustomFuncB1Null() { .. } - /** * Setter for native field CustomFuncB1, being a struct owned function pointer. *

@@ -634,7 +601,9 @@ and similar to `T2_InitializeOptions.customFuncB1` *

*/ public final long getCustomFuncB1() { .. } - + + /** Interface to C language function:
int32_t CustomFuncB1(T2_UserData * pUserData)
*/ + public final int CustomFuncB1(T2_UserData pUserData) { .. } ``` ## Platform Header Files diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java index 23aae96..cc86cac 100644 --- a/src/java/com/jogamp/gluegen/JavaEmitter.java +++ b/src/java/com/jogamp/gluegen/JavaEmitter.java @@ -1098,15 +1098,8 @@ public class JavaEmitter implements GlueEmitter { if ( fieldType.isFunctionPointer() && !isOpaqueField ) { final FunctionSymbol func = new FunctionSymbol(field.getName(), fieldType.asPointer().getTargetType().asFunction()); 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); @@ -1122,6 +1115,8 @@ public class JavaEmitter implements GlueEmitter { javaUnit.emitln(" return accessor.getLongAt(" + fieldName+"_offset[mdIdx], md.pointerSizeInBytes());"); javaUnit.emitln(" }"); javaUnit.emitln(); + generateFunctionPointerCode(methodBindingSet, javaUnit, jniUnit, structCTypeName, + containingCType, containingJType, i, func, fqStructFieldName1); } 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?) diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/Test2.java b/src/junit/com/jogamp/gluegen/test/junit/generation/Test2.java index 636eea7..28a3060 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/Test2.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test2.java @@ -82,20 +82,19 @@ public class Test2 extends BaseClass { 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()); + Assert.assertEquals(0, options.getCustomFuncA1()); + Assert.assertEquals(0, options.getCustomFuncA2()); + Assert.assertEquals(0, options.getCustomFuncB1()); + Assert.assertEquals(0, options.getCustomFuncB2()); 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.assertNotEquals(0, options.getCustomFuncA1()); + Assert.assertNotEquals(0, options.getCustomFuncA2()); + Assert.assertNotEquals(0, options.getCustomFuncB1()); + Assert.assertNotEquals(0, options.getCustomFuncB2()); Assert.assertEquals(1, options.getApiVersion()); Assert.assertEquals("Product Name", options.getProductName()); Assert.assertEquals("Product Version", options.getProductVersion()); @@ -135,10 +134,10 @@ public class Test2 extends BaseClass { 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()); + Assert.assertEquals(0, options.getCustomFuncA1()); + // const Assert.assertEquals(0, options.getCustomFuncA2()); + Assert.assertEquals(0, options.getCustomFuncB1()); + Assert.assertEquals(0, options.getCustomFuncB2()); } public static void main(final String args[]) throws IOException { 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 561b3ae..75eafcf 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.c +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.c @@ -24,13 +24,13 @@ static int32_t CustomFuncB2(T2_UserData* pUserData) { 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); + strncpy((char*)Options->ProductName, "Product Name", 100); // yuck: nonsense-warning + strncpy((char*)Options->ProductVersion, "Product Version", 100); // yuck: nonsense-warning Options->ApiVersion = 1; Options->Reserved1 = NULL; Options->CustomFuncA1 = CustomFuncA1; - Options->CustomFuncA2 = CustomFuncA2; + *( (T2_CustomFuncA*) &Options->CustomFuncA2 ) = CustomFuncA2; // yuck: real yuck Options->CustomFuncB1 = CustomFuncB1; Options->CustomFuncB2 = CustomFuncB2; @@ -39,15 +39,15 @@ int Initialize(T2_InitializeOptions* Options) { int Release(T2_InitializeOptions* Options) { if( NULL != Options->ProductName ) { - free( Options->ProductName ); + free( (void*) Options->ProductName ); // yuck: nonsense-warning Options->ProductName = NULL; } if( NULL != Options->ProductVersion ) { - free( Options->ProductVersion ); + free( (void*) Options->ProductVersion ); // yuck: nonsense-warning Options->ProductVersion = NULL; } Options->CustomFuncA1 = NULL; - Options->CustomFuncA2 = NULL; + // Options->CustomFuncA2 = NULL; // keep const Options->CustomFuncB1 = NULL; Options->CustomFuncB2 = NULL; } 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 0fca16a..cf0808d 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h @@ -29,7 +29,7 @@ typedef struct { void* Reserved1; T2_CustomFuncA CustomFuncA1; - T2_CustomFuncA CustomFuncA2; + const T2_CustomFuncA CustomFuncA2; T2_CustomFuncB CustomFuncB1; T2_CustomFuncB CustomFuncB2; -- cgit v1.2.3