mirror of https://github.com/kivy/pyjnius.git
added convert_python_to_jobject: don't do convert to java primitive/jvalue, but jobject. fixed array translation.
This commit is contained in:
parent
143ab371b6
commit
a2d0076e56
|
@ -253,6 +253,110 @@ cdef convert_jarray_to_python(JNIEnv *j_env, definition, jobject j_object):
|
|||
|
||||
return ret
|
||||
|
||||
cdef jobject convert_python_to_jobject(JNIEnv *j_env, definition, obj) except *:
|
||||
cdef jobject retobject, retsubobject
|
||||
cdef jclass retclass
|
||||
cdef jmethodID redmidinit
|
||||
cdef jvalue j_ret[1]
|
||||
cdef JavaClass jc
|
||||
cdef JavaObject jo
|
||||
cdef JavaClassStorage jcs
|
||||
cdef PythonJavaClass pc
|
||||
cdef int index
|
||||
|
||||
print 'convert_python_to_jobject()', definition, repr(obj)
|
||||
|
||||
if definition[0] == 'L':
|
||||
if obj is None:
|
||||
return NULL
|
||||
elif isinstance(obj, basestring) and \
|
||||
definition in ('Ljava/lang/String;', 'Ljava/lang/Object;'):
|
||||
return j_env[0].NewStringUTF(j_env, <char *><bytes>obj)
|
||||
elif isinstance(obj, type):
|
||||
jc = obj
|
||||
return jc.j_cls
|
||||
elif isinstance(obj, JavaClass):
|
||||
jc = obj
|
||||
check_assignable_from(j_env, jc, definition[1:-1])
|
||||
return jc.j_self.obj
|
||||
elif isinstance(obj, JavaObject):
|
||||
jo = obj
|
||||
return jo.obj
|
||||
elif isinstance(obj, MetaJavaClass):
|
||||
jcs = obj.__cls_storage
|
||||
return jcs.j_cls
|
||||
elif isinstance(obj, PythonJavaClass):
|
||||
# from python class, get the proxy/python class
|
||||
pc = obj
|
||||
# get the java class
|
||||
jc = pc.j_self
|
||||
# get the localref
|
||||
return jc.j_self.obj
|
||||
elif isinstance(obj, (tuple, list)):
|
||||
return convert_pyarray_to_java(j_env, definition, obj)
|
||||
else:
|
||||
raise JavaException('Invalid python object for this '
|
||||
'argument. Want {0!r}, got {1!r}'.format(
|
||||
definition[1:-1], obj))
|
||||
|
||||
elif definition[0] == '[':
|
||||
conversions = {
|
||||
int: 'I',
|
||||
bool: 'Z',
|
||||
long: 'J',
|
||||
float: 'F',
|
||||
basestring: 'Ljava/lang/String;',
|
||||
}
|
||||
retclass = j_env[0].FindClass(j_env, 'java/lang/Object')
|
||||
retobject = j_env[0].NewObjectArray(j_env, len(obj), retclass, NULL)
|
||||
for index, item in enumerate(obj):
|
||||
item_definition = conversions.get(type(item), definition[1:])
|
||||
retsubobject = convert_python_to_jobject(
|
||||
j_env, item_definition, item)
|
||||
j_env[0].SetObjectArrayElement(j_env, retobject, index,
|
||||
retsubobject)
|
||||
return retobject
|
||||
|
||||
elif definition == 'B':
|
||||
retclass = j_env[0].FindClass(j_env, 'java/lang/Byte')
|
||||
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(B)V')
|
||||
j_ret[0].b = obj
|
||||
elif definition == 'S':
|
||||
retclass = j_env[0].FindClass(j_env, 'java/lang/Short')
|
||||
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(S)V')
|
||||
j_ret[0].s = obj
|
||||
elif definition == 'I':
|
||||
retclass = j_env[0].FindClass(j_env, 'java/lang/Integer')
|
||||
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(I)V')
|
||||
j_ret[0].i = obj
|
||||
elif definition == 'J':
|
||||
retclass = j_env[0].FindClass(j_env, 'java/lang/Long')
|
||||
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(J)V')
|
||||
j_ret[0].j = obj
|
||||
elif definition == 'F':
|
||||
retclass = j_env[0].FindClass(j_env, 'java/lang/Float')
|
||||
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(F)V')
|
||||
j_ret[0].f = obj
|
||||
elif definition == 'D':
|
||||
retclass = j_env[0].FindClass(j_env, 'java/lang/Double')
|
||||
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(D)V')
|
||||
j_ret[0].d = obj
|
||||
elif definition == 'C':
|
||||
retclass = j_env[0].FindClass(j_env, 'java/lang/Char')
|
||||
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(C)V')
|
||||
j_ret[0].c = ord(obj)
|
||||
elif definition == 'Z':
|
||||
retclass = j_env[0].FindClass(j_env, 'java/lang/Boolean')
|
||||
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(Z)V')
|
||||
j_ret[0].z = 1 if obj else 0
|
||||
else:
|
||||
assert(0)
|
||||
|
||||
assert(retclass != NULL)
|
||||
# XXX do we need a globalref or something ?
|
||||
retobject = j_env[0].NewObjectA(j_env, retclass, retmidinit, j_ret)
|
||||
return retobject
|
||||
|
||||
|
||||
cdef jobject convert_pyarray_to_java(JNIEnv *j_env, definition, pyarray) except *:
|
||||
cdef jobject ret = NULL
|
||||
|
@ -271,6 +375,7 @@ cdef jobject convert_pyarray_to_java(JNIEnv *j_env, definition, pyarray) except
|
|||
cdef JavaObject jo
|
||||
cdef JavaClass jc
|
||||
|
||||
|
||||
if definition == 'Ljava/lang/Object;' and len(pyarray) > 0:
|
||||
# then the method will accept any array type as param
|
||||
# let's be as precise as we can
|
||||
|
|
|
@ -357,11 +357,7 @@ cdef jobject invoke0(JNIEnv *j_env, jobject j_this, jobject j_proxy, jobject
|
|||
|
||||
# convert back to the return type
|
||||
# use the populate_args(), but in the reverse way :)
|
||||
cdef jvalue j_ret[1]
|
||||
t = ret_signature[:1]
|
||||
cdef jclass retclass = NULL
|
||||
cdef jobject retobject
|
||||
cdef jmethodID retmidinit
|
||||
|
||||
# did python returned a "native" type ?
|
||||
jtype = None
|
||||
|
@ -378,56 +374,13 @@ cdef jobject invoke0(JNIEnv *j_env, jobject j_this, jobject j_proxy, jobject
|
|||
elif len(ret_signature) == 1:
|
||||
jtype = ret_signature
|
||||
|
||||
# converting a native type to an Object for returning the value
|
||||
if jtype is not None:
|
||||
if jtype == 'B':
|
||||
retclass = j_env[0].FindClass(j_env, 'java/lang/Byte')
|
||||
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(B)V')
|
||||
j_ret[0].b = ret
|
||||
elif jtype == 'S':
|
||||
retclass = j_env[0].FindClass(j_env, 'java/lang/Short')
|
||||
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(S)V')
|
||||
j_ret[0].s = ret
|
||||
elif jtype == 'I':
|
||||
retclass = j_env[0].FindClass(j_env, 'java/lang/Integer')
|
||||
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(I)V')
|
||||
j_ret[0].i = ret
|
||||
elif jtype == 'J':
|
||||
retclass = j_env[0].FindClass(j_env, 'java/lang/Long')
|
||||
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(J)V')
|
||||
j_ret[0].j = ret
|
||||
elif jtype == 'F':
|
||||
retclass = j_env[0].FindClass(j_env, 'java/lang/Float')
|
||||
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(F)V')
|
||||
j_ret[0].f = ret
|
||||
elif jtype == 'D':
|
||||
retclass = j_env[0].FindClass(j_env, 'java/lang/Double')
|
||||
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(D)V')
|
||||
j_ret[0].d = ret
|
||||
elif jtype == 'C':
|
||||
retclass = j_env[0].FindClass(j_env, 'java/lang/Char')
|
||||
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(C)V')
|
||||
j_ret[0].c = ord(ret)
|
||||
elif jtype == 'Z':
|
||||
retclass = j_env[0].FindClass(j_env, 'java/lang/Boolean')
|
||||
retmidinit = j_env[0].GetMethodID(j_env, retclass, '<init>', '(Z)V')
|
||||
j_ret[0].z = 1 if ret else 0
|
||||
else:
|
||||
print 'jtype', jtype
|
||||
assert(0)
|
||||
|
||||
if retclass != NULL:
|
||||
# XXX do we need a globalref or something ?
|
||||
retobject = j_env[0].NewObjectA(j_env, retclass, retmidinit, j_ret)
|
||||
return retobject
|
||||
|
||||
# this is not a "native" type, so we should be able to convert it to object
|
||||
# with populate_args().
|
||||
# (String, list/tuple, etc.)
|
||||
populate_args(j_env, (ret_signature, ), <jvalue *>j_ret, [ret])
|
||||
return j_ret[0].l
|
||||
|
||||
cdef jobject jret
|
||||
|
||||
try:
|
||||
jret = convert_python_to_jobject(j_env, jtype or ret_signature, ret)
|
||||
return jret
|
||||
except Exception as e:
|
||||
traceback.print_exc(e)
|
||||
|
||||
|
||||
|
||||
|
@ -465,6 +418,7 @@ def test():
|
|||
from .reflect import autoclass
|
||||
|
||||
print '1: declare a TestImplem that implement Collection'
|
||||
|
||||
class TestImplemIterator(PythonJavaClass):
|
||||
__javainterfaces__ = ['java/util/Iterator']
|
||||
|
||||
|
@ -522,7 +476,7 @@ def test():
|
|||
return self.data
|
||||
|
||||
print '2: instanciate the class, with some data'
|
||||
a = TestImplem(1, 2, 3)
|
||||
a = TestImplem(*range(10))
|
||||
print a
|
||||
print dir(a)
|
||||
|
||||
|
|
Loading…
Reference in New Issue