From 5ceca8550b82591a6a2661a26d3e0d5e6e3e15ff Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Wed, 5 Jul 2023 10:21:48 +0200 Subject: GlueGen: Add 'PascalString' string semantics (length + value-ptr), added prelim code for JavaCallback use-case emitBodyMapCToJNIType() It is common in toolkit APIs that a string might not be passed as a 'nul' terminated (EOS) C string, but as a Pascal string with a given length argument. A C string is specied as ArgumentIsString alEventCallbackInject 3 while allowing multiple indices .. A Pascal string can be specified as ArgumentIsPascalString ALEVENTPROCSOFT 3 4 while allowing multiple indice-tuples for length and value .. The tuple consist of the length agrument-index first (usually an int) followed by the value argument-index (usually a 'char*'). +++ CMethodBindingEmitter.emitBodyMapCToJNIType(), where PascalString is implemented, is currently being used for - JNI return statement (no PascalString impact possible) - JavaCallback C type -> JNI type, PascalString impacting --- .../com/jogamp/gluegen/CMethodBindingEmitter.java | 30 +++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'src/java/com/jogamp/gluegen/CMethodBindingEmitter.java') diff --git a/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java b/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java index 9c7ed0b..e20a1cb 100644 --- a/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java +++ b/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java @@ -1176,12 +1176,36 @@ public class CMethodBindingEmitter extends FunctionEmitter { unit.emitln(" */"); } } else if (javaType.isString()) { + final boolean pascalString = javaType.isPascalStringVariant(); + final String lenArgName; + if( pascalString ) { + final int lenIdx = cfg.pascalStringLengthIndex(getCSymbol(), argIdx); + lenArgName = 0 <= lenIdx ? binding.getArgumentName(lenIdx) : null; + } else { + lenArgName = null; + } if( addLocalVar ) { - unit.emit(" "+javaType.jniTypeName()+" "+javaArgName+" = "); + unit.emitln(" "+javaType.jniTypeName()+" "+javaArgName+";"); + } + if( null != lenArgName ) { + unit.emitln(" if (NULL == "+cArgName+" || 0 >= "+lenArgName+" ) {"); } else { - unit.emit(" "+javaArgName+" = "); + unit.emitln(" if (NULL == "+cArgName+") {"); + } + unit.emitln(" "+javaArgName+" = NULL;"); + unit.emitln(" } else {"); + if( null != lenArgName ) { + unit.emitln(" char* "+cArgName+"_cstr = calloc("+lenArgName+"+1, sizeof(char)); // PascalString -> Add EOS"); + unit.emitln(" memcpy("+cArgName+"_cstr, "+cArgName+", "+lenArgName+");"); } - unit.emitln("(NULL == "+cArgName+") ? NULL : (*env)->NewStringUTF(env, (const char *)"+cArgName+");"); + unit.emit (" "+javaArgName+" = "); + if( null != lenArgName ) { + unit.emitln("(*env)->NewStringUTF(env, (const char *)"+cArgName+"_cstr);"); + unit.emitln(" free("+cArgName+"_cstr);"); + } else { + unit.emitln("(*env)->NewStringUTF(env, (const char *)"+cArgName+");"); + } + unit.emitln(" }"); } else if (javaType.isArrayOfCompoundTypeWrappers() || ( javaType.isArray() && javaType.isNIOByteBufferArray() ) ) { -- cgit v1.2.3