diff options
author | Michal Cmarada <mcmarada@cisco.com> | 2019-01-31 10:57:40 +0100 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2019-02-19 15:14:02 +0000 |
commit | 4e633e1043e867fd24badeb0405f794793beb9a9 (patch) | |
tree | acc92341b32be50bdef030becb2c65efe5252da2 /extras/japi/java/jvpp/gen/jvppgen/jni_common_gen.py | |
parent | aed61801947146e6a93e7791d382bd21d050ee14 (diff) |
VPP-1504: Remove JVPP
As part of JVPP migration this removes JVPP completely from VPP.
Change-Id: I6b74e7961aa474ae471e63fe43a624cd9fc3659b
Signed-off-by: Michal Cmarada <mcmarada@cisco.com>
Diffstat (limited to 'extras/japi/java/jvpp/gen/jvppgen/jni_common_gen.py')
-rwxr-xr-x | extras/japi/java/jvpp/gen/jvppgen/jni_common_gen.py | 482 |
1 files changed, 0 insertions, 482 deletions
diff --git a/extras/japi/java/jvpp/gen/jvppgen/jni_common_gen.py b/extras/japi/java/jvpp/gen/jvppgen/jni_common_gen.py deleted file mode 100755 index b52e5ff2d2c..00000000000 --- a/extras/japi/java/jvpp/gen/jvppgen/jni_common_gen.py +++ /dev/null @@ -1,482 +0,0 @@ -#!/usr/bin/env python2 -# -# Copyright (c) 2018 Cisco and/or its affiliates. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from string import Template - -from jvpp_model import is_array, is_retval, Class, Enum, Union - - -def generate_j2c_identifiers(element, class_ref_name, object_ref_name): - identifiers = [] - for field in element.fields: - field_type = field.type - identifiers.append(_REQUEST_FIELD_IDENTIFIER_TEMPLATE.substitute( - java_name=field.java_name, - class_ref_name=class_ref_name, - jni_signature=field_type.jni_signature, - jni_type=field_type.jni_type, - jni_accessor=field_type.jni_accessor, - object_ref_name=object_ref_name - )) - return "".join(identifiers) - -_REQUEST_FIELD_IDENTIFIER_TEMPLATE = Template(""" - jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}, "${java_name}", "${jni_signature}"); - ${jni_type} ${java_name} = (*env)->Get${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId); -""") - - -# TODO(VPP-1187): do not inline JNI object creation inside message handlers to reduce number of special cases -def generate_j2c_swap(element, struct_ref_name, is_alias): - initialization = [] - for field in element.fields: - initialization.append(generate_j2c_field_swap(field, struct_ref_name, is_alias)) - return "\n".join(initialization) - - -def generate_j2c_field_swap(field, struct_ref_name, is_alias): - if is_array(field): - return _generate_j2c_array_swap(field, struct_ref_name, is_alias) - else: - return _generate_j2c_scalar_swap(field, struct_ref_name, is_alias) - - -def _generate_j2c_array_swap(field, struct_ref_name, is_alias): - # TODO(VPP-1186): move the logic to JNI generators - base_type = field.type.base_type - if isinstance(base_type, (Class, Enum, Union)): - return _generate_j2c_object_array_swap(field, struct_ref_name) - elif base_type.is_swap_needed: - return _generate_j2c_primitive_type_array_swap(field, struct_ref_name) - else: - return _generate_j2c_primitive_type_array_no_swap(field, struct_ref_name, is_alias) - - -def _generate_j2c_object_array_swap(field, struct_ref_name): - field_type = field.type - field_reference_name = field.java_name - c_name = field.name - host = "%sArrayElement" % field_reference_name - net = "%s->%s[_i]" % (struct_ref_name, c_name) - swap_elements = field_type.get_host_to_net_function(host, net) - return _J2C_OBJECT_ARRAY_SWAP_TEMPLATE.substitute( - field_reference_name=field_reference_name, - field_length_check=_generate_field_length_check(field), - swap_elements=swap_elements) - -_J2C_OBJECT_ARRAY_SWAP_TEMPLATE = Template(""" - { - if (${field_reference_name}) { - size_t _i; - jsize cnt = (*env)->GetArrayLength (env, ${field_reference_name}); - ${field_length_check} - for (_i = 0; _i < cnt; _i++) { - jobject ${field_reference_name}ArrayElement = (*env)->GetObjectArrayElement(env, ${field_reference_name}, _i); - ${swap_elements}; - } - } - } -""") - - -def _generate_j2c_primitive_type_array_swap(field, struct_ref_name): - field_reference_name = field.java_name - field_type = field.type - host = "%sArrayElements[_i]" % field_reference_name - net = "%s->%s[_i]" % (struct_ref_name, field.name) - swap_elements = field_type.get_host_to_net_function(host, net) - return _J2C_PRIMITIVE_TYPE_ARRAY_SWAP_TEMPLATE.substitute( - field_reference_name=field_reference_name, - field_length_check=_generate_field_length_check(field), - base_type=field_type.base_type.jni_accessor, - jni_base_type=field_type.base_type.jni_type, - swap_elements=swap_elements - ) - -_J2C_PRIMITIVE_TYPE_ARRAY_SWAP_TEMPLATE = Template(""" - if (${field_reference_name}) { - ${jni_base_type} * ${field_reference_name}ArrayElements = (*env)->Get${base_type}ArrayElements(env, ${field_reference_name}, NULL); - size_t _i; - jsize cnt = (*env)->GetArrayLength(env, ${field_reference_name}); - ${field_length_check} - for (_i = 0; _i < cnt; _i++) { - ${swap_elements}; - } - (*env)->Release${base_type}ArrayElements (env, ${field_reference_name}, ${field_reference_name}ArrayElements, 0); - } - """) - - -def _generate_j2c_primitive_type_array_no_swap(field, struct_ref_name, is_alias): - field_type = field.type - if not is_alias: - template = _J2C_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE - else: - template = _J2C_ALIAS_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE - - return template.substitute( - field_reference_name=field.java_name, - field_length_check=_generate_field_length_check(field), - base_type=field_type.base_type.jni_accessor, - jni_base_type=field_type.base_type.jni_type, - struct_reference_name=struct_ref_name, - c_name=field.name - ) - -_J2C_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE = Template(""" - if (${field_reference_name}) { - jsize cnt = (*env)->GetArrayLength (env, ${field_reference_name}); - ${field_length_check} - (*env)->Get${base_type}ArrayRegion(env, ${field_reference_name}, 0, cnt, (${jni_base_type} *)${struct_reference_name}->${c_name}); - } -""") - - -_J2C_ALIAS_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE = Template(""" - if (${field_reference_name}) { - jsize cnt = (*env)->GetArrayLength (env, ${field_reference_name}); - ${field_length_check} - (*env)->Get${base_type}ArrayRegion(env, ${field_reference_name}, 0, cnt, (${jni_base_type} *)${struct_reference_name}); - } -""") - - -def _generate_field_length_check(field): - # Enforce max length if array has fixed length or uses variable length syntax - field_length = str(field.array_len) - if field.array_len_field: - field_length = field.array_len_field.java_name - - # TODO: remove when ZLAs without length field are disabled - if field_length != "0": - return _FIELD_LENGTH_CHECK.substitute(field_length=field_length) - else: - return "" - - -# Make sure we do not write more elements that are expected -_FIELD_LENGTH_CHECK = Template(""" - size_t max_size = ${field_length}; - if (cnt > max_size) cnt = max_size;""") - - -def _generate_j2c_scalar_swap(field, struct_ref_name, is_alias): - field_type = field.type - if field_type.is_swap_needed: - host = field.java_name - if not is_alias: - net = "%s->%s" % (struct_ref_name, field.name) - if field_type.name == "string": - net = "%s->%s" % (struct_ref_name, field.name) - return " _host_to_net_%s(env, %s, (vl_api_string_t *) &%s);" % (field_type.name, host, net) - else: - return " %s;" % field_type.get_host_to_net_function(host, net) - else: - net = "%s" % struct_ref_name - return " *%s;" % field_type.get_host_to_net_function(host, net) - else: - return " %s->%s = %s;" % (struct_ref_name, field.name, field.java_name) - - -def generate_c2j_swap(element, object_ref_name, struct_ref_name, is_alias): - msg_java_name = element.java_name_lower - initialization = [] - for field in element.fields: - if is_retval(field): - # For retval don't generate setters and generate retval check - continue - elif is_array(field): - initialization.append(_generate_c2j_array_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias)) - else: - initialization.append(_generate_c2j_scalar_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias)) - return "".join(initialization) - - -def _generate_c2j_array_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias): - # TODO(VPP-1186): move the logic to JNI generators - base_type = field.type.base_type - if isinstance(base_type, (Class, Union)): - return _generate_c2j_object_array_swap(msg_java_name, field, object_ref_name, struct_ref_name) - elif isinstance(base_type, Enum): - return _generate_c2j_enum_array_swap(msg_java_name, field, object_ref_name, struct_ref_name) - elif base_type.is_swap_needed: - return _generate_c2j_primitive_type_array_swap(msg_java_name, field, object_ref_name, struct_ref_name) - else: - return _generate_c2j_primitive_type_array_no_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias) - - -def _generate_c2j_object_array_swap(msg_java_name, field, object_ref_name, struct_ref_name): - field_type = field.type - return _C2J_OBJECT_ARRAY_SWAP_TEMPLATE.substitute( - field_reference_name=field.java_name, - class_ref_name=msg_java_name, - jni_signature=field_type.jni_signature, - jni_name=field_type.base_type.jni_name, - field_length=_generate_array_length(field, struct_ref_name), - net_to_host_function=field_type.net_to_host_function, - struct_ref_name=struct_ref_name, - object_ref_name=object_ref_name, - c_name=field.name - ) - -_C2J_OBJECT_ARRAY_SWAP_TEMPLATE = Template(""" - jfieldID ${field_reference_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${field_reference_name}", "${jni_signature}"); - { - jclass ${field_reference_name}Class = (*env)->FindClass(env, "${jni_name}"); - jobjectArray ${field_reference_name} = (*env)->NewObjectArray(env, ${field_length}, ${field_reference_name}Class, 0); - jmethodID ${field_reference_name}Constructor = (*env)->GetMethodID(env, ${field_reference_name}Class, "<init>", "()V"); - unsigned int _i; - for (_i = 0; _i < ${field_length}; _i++) { - jobject ${field_reference_name}ArrayElement = (*env)->NewObject(env, ${field_reference_name}Class, ${field_reference_name}Constructor); - ${net_to_host_function}(env, &(${struct_ref_name}->${c_name}[_i]), ${field_reference_name}ArrayElement); - (*env)->SetObjectArrayElement(env, ${field_reference_name}, _i, ${field_reference_name}ArrayElement); - (*env)->DeleteLocalRef(env, ${field_reference_name}ArrayElement); - } - (*env)->SetObjectField(env, ${object_ref_name}, ${field_reference_name}FieldId, ${field_reference_name}); - (*env)->DeleteLocalRef(env, ${field_reference_name}); - } -""") - - -def _generate_c2j_enum_array_swap(msg_java_name, field, object_ref_name, struct_ref_name): - field_type = field.type - base_type = field_type.base_type - return _C2J_ENUM_ARRAY_SWAP_TEMPLATE.substitute( - field_reference_name=field.java_name, - class_ref_name=msg_java_name, - jni_signature=field_type.jni_signature, - jni_name=base_type.jni_name, - field_length=_generate_array_length(field, struct_ref_name), - net_to_host_function=field_type.net_to_host_function, - jni_signature_enum_value=base_type.value.type.jni_signature, - struct_ref_name=struct_ref_name, - object_ref_name=object_ref_name, - c_name=field.name - ) - -_C2J_ENUM_ARRAY_SWAP_TEMPLATE = Template(""" - jfieldID ${field_reference_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${field_reference_name}", "${jni_signature}"); - { - jclass ${field_reference_name}Class = (*env)->FindClass(env, "${jni_name}"); - jobjectArray ${field_reference_name} = (*env)->NewObjectArray(env, ${field_length}, ${field_reference_name}Class, 0); - jmethodID ${field_reference_name}Constructor = (*env)->GetStaticMethodID(env, ${field_reference_name}Class, "forValue", "(${jni_signature_enum_value})${jni_signature}"); - unsigned int _i; - for (_i = 0; _i < ${field_length}; _i++) { - jobject ${field_reference_name}ArrayElement = (*env)->CallStaticObjectMethod(env, ${field_reference_name}Class, ${field_reference_name}Constructor, ${net_to_host_function}(${struct_ref_name}->${c_name}[_i])); - (*env)->SetObjectArrayElement(env, ${field_reference_name}, _i, ${field_reference_name}ArrayElement); - (*env)->DeleteLocalRef(env, ${field_reference_name}ArrayElement); - } - (*env)->SetObjectField(env, ${object_ref_name}, ${field_reference_name}FieldId, ${field_reference_name}); - (*env)->DeleteLocalRef(env, ${field_reference_name}); - } -""") - - -def _generate_c2j_primitive_type_array_swap(msg_java_name, field, object_ref_name, struct_ref_name): - field_type = field.type - return _C2J_PRIMITIVE_TYPE_ARRAY_SWAP_TEMPLATE.substitute( - field_reference_name=field.java_name, - class_ref_name=msg_java_name, - jni_signature=field_type.jni_signature, - jni_type=field_type.jni_type, - base_type=field_type.base_type.jni_accessor, - field_length=_generate_array_length(field, struct_ref_name), - jni_base_type=field_type.base_type.jni_type, - object_ref_name=object_ref_name, - struct_ref_name=struct_ref_name, - net_to_host_function=field_type.net_to_host_function, - c_name=field.name - ) - -_C2J_PRIMITIVE_TYPE_ARRAY_SWAP_TEMPLATE = Template(""" - jfieldID ${field_reference_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${field_reference_name}", "${jni_signature}"); - { - ${jni_type} ${field_reference_name} = (*env)->New${base_type}Array(env, ${field_length}); - ${jni_base_type} * ${field_reference_name}ArrayElements = (*env)->Get${base_type}ArrayElements(env, ${field_reference_name}, NULL); - unsigned int _i; - for (_i = 0; _i < ${field_length}; _i++) { - ${field_reference_name}ArrayElements[_i] = ${net_to_host_function}(${struct_ref_name}->${c_name}[_i]); - } - - (*env)->Release${base_type}ArrayElements(env, ${field_reference_name}, ${field_reference_name}ArrayElements, 0); - (*env)->SetObjectField(env, ${object_ref_name}, ${field_reference_name}FieldId, ${field_reference_name}); - (*env)->DeleteLocalRef(env, ${field_reference_name}); - } -""") - - -def _generate_c2j_primitive_type_array_no_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias): - field_type = field.type - if not is_alias: - template = _C2J_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE - else: - template = _C2J_ALIAS_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE - return template.substitute( - field_reference_name=field.java_name, - class_ref_name=msg_java_name, - jni_signature=field_type.jni_signature, - jni_type=field_type.jni_type, - base_type=field_type.base_type.jni_accessor, - field_length=_generate_array_length(field, struct_ref_name), - jni_base_type=field_type.base_type.jni_type, - object_ref_name=object_ref_name, - struct_ref_name=struct_ref_name, - c_name=field.name - ) - -_C2J_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE = Template(""" - jfieldID ${field_reference_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${field_reference_name}", "${jni_signature}"); - ${jni_type} ${field_reference_name} = (*env)->New${base_type}Array(env, ${field_length}); - (*env)->Set${base_type}ArrayRegion(env, ${field_reference_name}, 0, ${field_length}, (const ${jni_base_type}*)${struct_ref_name}->${c_name}); - (*env)->SetObjectField(env, ${object_ref_name}, ${field_reference_name}FieldId, ${field_reference_name}); - (*env)->DeleteLocalRef(env, ${field_reference_name}); -""") - - -_C2J_ALIAS_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE = Template(""" - jfieldID ${field_reference_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${field_reference_name}", "${jni_signature}"); - ${jni_type} ${field_reference_name} = (*env)->New${base_type}Array(env, ${field_length}); - (*env)->Set${base_type}ArrayRegion(env, ${field_reference_name}, 0, ${field_length}, (const ${jni_base_type}*)${struct_ref_name}); - (*env)->SetObjectField(env, ${object_ref_name}, ${field_reference_name}FieldId, ${field_reference_name}); - (*env)->DeleteLocalRef(env, ${field_reference_name}); -""") - - -def _generate_array_length(field, struct_ref_name): - if field.array_len_field: - len_field = field.array_len_field - if len_field.type.is_swap_needed: - return "%s(%s->%s)" % (len_field.type.host_to_net_function, struct_ref_name, len_field.name) - else: - return "%s->%s" % (struct_ref_name, len_field.name) - return field.array_len - - -def _generate_c2j_scalar_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias): - field_type = field.type - if field_type.is_swap_needed: - # TODO(VPP-1186): move the logic to JNI generators - if isinstance(field_type, (Class, Union)): - return _generate_c2j_object_swap(msg_java_name, field, object_ref_name, struct_ref_name) - elif isinstance(field_type, Enum): - return _generate_c2j_enum_swap(msg_java_name, field, object_ref_name, struct_ref_name) - else: - return _generate_c2j_primitive_type_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias) - else: - return _generate_c2j_primitive_type_no_swap(msg_java_name, field, object_ref_name, struct_ref_name) - - -def _generate_c2j_object_swap(msg_java_name, field, object_ref_name, struct_ref_name): - field_type = field.type - return _C2J_OBJECT_SWAP_TEMPLATE.substitute( - java_name=field.java_name, - class_ref_name=msg_java_name, - jni_signature=field_type.jni_signature, - jni_name=field_type.jni_name, - jni_accessor=field_type.jni_accessor, - object_ref_name=object_ref_name, - struct_ref_name=struct_ref_name, - net_to_host_function=field_type.net_to_host_function, - c_name=field.name) - -_C2J_OBJECT_SWAP_TEMPLATE = Template(""" - jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}"); - jclass ${java_name}Class = (*env)->FindClass(env, "${jni_name}"); - jmethodID ${java_name}Constructor = (*env)->GetMethodID(env, ${java_name}Class, "<init>", "()V"); - jobject ${java_name} = (*env)->NewObject(env, ${java_name}Class, ${java_name}Constructor); - ${net_to_host_function}(env, &(${struct_ref_name}->${c_name}), ${java_name}); - (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${java_name}); - (*env)->DeleteLocalRef(env, ${java_name}); -""") - - -def _generate_c2j_enum_swap(msg_java_name, field, object_ref_name, struct_ref_name): - field_type = field.type - return _C2J_ENUM_SWAP_TEMPLATE.substitute( - java_name=field.java_name, - class_ref_name=msg_java_name, - jni_signature=field_type.jni_signature, - jni_signature_enum_value=field_type.value.type.jni_signature, - jni_name=field_type.jni_name, - jni_accessor=field_type.jni_accessor, - object_ref_name=object_ref_name, - struct_ref_name=struct_ref_name, - net_to_host_function=field_type.net_to_host_function, - c_name=field.name) - -_C2J_ENUM_SWAP_TEMPLATE = Template(""" - jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}"); - jclass ${java_name}Class = (*env)->FindClass(env, "${jni_name}"); - jmethodID ${java_name}Constructor = (*env)->GetStaticMethodID(env, ${java_name}Class, "forValue", "(${jni_signature_enum_value})${jni_signature}"); - jobject ${java_name} = (*env)->CallStaticObjectMethod(env, ${java_name}Class, ${java_name}Constructor, ${net_to_host_function}(${struct_ref_name}->${c_name})); - (*env)->SetObjectField(env, ${object_ref_name}, ${java_name}FieldId, ${java_name}); - (*env)->DeleteLocalRef(env, ${java_name}); -""") - - -def _generate_c2j_primitive_type_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias): - field_type = field.type - if not is_alias: - if field_type.name == "string": - template = _C2J_STRING_TYPE_SWAP_TEMPLATE - else: - template = _C2J_PRIMITIVE_TYPE_SWAP_TEMPLATE - else: - template = _C2J_ALIAS_PRIMITIVE_TYPE_SWAP_TEMPLATE - return template.substitute( - java_name=field.java_name, - class_ref_name=msg_java_name, - jni_signature=field_type.jni_signature, - jni_accessor=field_type.jni_accessor, - object_ref_name=object_ref_name, - net_to_host_function=field_type.net_to_host_function, - struct_ref_name=struct_ref_name, - c_name=field.name - ) - -_C2J_PRIMITIVE_TYPE_SWAP_TEMPLATE = Template(""" - jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}"); - (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${net_to_host_function}(${struct_ref_name}->${c_name})); -""") - - -_C2J_STRING_TYPE_SWAP_TEMPLATE = Template(""" - jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}"); - (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${net_to_host_function}(env, (const vl_api_string_t *) &${struct_ref_name}->${c_name})); -""") - - -_C2J_ALIAS_PRIMITIVE_TYPE_SWAP_TEMPLATE = Template(""" - jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}"); - (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${net_to_host_function}(*${struct_ref_name})); -""") - - -def _generate_c2j_primitive_type_no_swap(msg_java_name, field, object_ref_name, struct_ref_name): - field_type = field.type - return _C2J_PRIMITIVE_TYPE_NO_SWAP_TEMPLATE.substitute( - java_name=field.java_name, - class_ref_name=msg_java_name, - jni_signature=field_type.jni_signature, - jni_accessor=field_type.jni_accessor, - object_ref_name=object_ref_name, - struct_ref_name=struct_ref_name, - c_name=field.name - ) - -_C2J_PRIMITIVE_TYPE_NO_SWAP_TEMPLATE = Template(""" - jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}"); - (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${struct_ref_name}->${c_name}); -""") |