allow for argument specific pass by reference / value settings

This commit is contained in:
Jim 2020-06-11 14:46:09 -04:00
parent 6542d7dcf1
commit b838402897
2 changed files with 16 additions and 4 deletions

View File

@ -7,11 +7,15 @@ cdef jstringy_arg(argtype):
'Ljava/lang/CharSequence;', 'Ljava/lang/CharSequence;',
'Ljava/lang/Object;') 'Ljava/lang/Object;')
cdef void release_args(JNIEnv *j_env, tuple definition_args, bint pass_by_reference, jvalue *j_args, args) except *: cdef void release_args(JNIEnv *j_env, tuple definition_args, pass_by_reference, jvalue *j_args, args) except *:
# do the conversion from a Python object to Java from a Java definition # do the conversion from a Python object to Java from a Java definition
cdef JavaObject jo cdef JavaObject jo
cdef JavaClass jc cdef JavaClass jc
cdef int index cdef int index
cdef int last_pass_by_ref_index
last_pass_by_ref_index = len(pass_by_reference) - 1
for index, argtype in enumerate(definition_args): for index, argtype in enumerate(definition_args):
py_arg = args[index] py_arg = args[index]
if argtype[0] == 'L': if argtype[0] == 'L':
@ -21,7 +25,7 @@ cdef void release_args(JNIEnv *j_env, tuple definition_args, bint pass_by_refere
jstringy_arg(argtype): jstringy_arg(argtype):
j_env[0].DeleteLocalRef(j_env, j_args[index].l) j_env[0].DeleteLocalRef(j_env, j_args[index].l)
elif argtype[0] == '[': elif argtype[0] == '[':
if pass_by_reference and hasattr(args[index], '__setitem__'): if pass_by_reference[min(index, last_pass_by_ref_index)] and hasattr(args[index], '__setitem__'):
ret = convert_jarray_to_python(j_env, argtype[1:], j_args[index].l) ret = convert_jarray_to_python(j_env, argtype[1:], j_args[index].l)
try: try:
args[index][:] = ret args[index][:] = ret

View File

@ -360,12 +360,16 @@ cdef class JavaClass(object):
raise JavaException('Unable to found the constructor' raise JavaException('Unable to found the constructor'
' for {0}'.format(self.__javaclass__)) ' for {0}'.format(self.__javaclass__))
# determine pass by reference choices
pass_by_reference = kwargs.get('pass_by_reference', True)
pass_by_reference = pass_by_reference if isinstance(pass_by_reference, (tuple, list)) else [pass_by_reference]
# create the object # create the object
j_self = j_env[0].NewObjectA(j_env, self.j_cls, j_self = j_env[0].NewObjectA(j_env, self.j_cls,
constructor, j_args) constructor, j_args)
# release our arguments # release our arguments
release_args(j_env, d_args, kwargs.get('pass_by_reference', True), j_args, args_) release_args(j_env, d_args, pass_by_reference, j_args, args_)
check_exception(j_env) check_exception(j_env)
if j_self == NULL: if j_self == NULL:
@ -835,6 +839,10 @@ cdef class JavaMethod(object):
self.classname, self.name) self.classname, self.name)
) )
# determine pass by reference choices
pass_by_reference = kwargs.get('pass_by_reference', True)
pass_by_reference = pass_by_reference if isinstance(pass_by_reference, (tuple, list)) else [pass_by_reference]
if not self.is_static and j_env == NULL: if not self.is_static and j_env == NULL:
raise JavaException( raise JavaException(
'Cannot call instance method on a un-instanciated class' 'Cannot call instance method on a un-instanciated class'
@ -856,7 +864,7 @@ cdef class JavaMethod(object):
return self.call_staticmethod(j_env, j_args) return self.call_staticmethod(j_env, j_args)
return self.call_method(j_env, j_args) return self.call_method(j_env, j_args)
finally: finally:
release_args(j_env, self.definition_args, kwargs.get('pass_by_reference', True), j_args, args) release_args(j_env, self.definition_args, pass_by_reference, j_args, args)
finally: finally:
if j_args != NULL: if j_args != NULL: