40 rtl_uString * pOid =
nullptr;
42 assert( pOid !=
nullptr );
43 OUString oid( pOid, SAL_NO_ACQUIRE );
50 jobject jo_iface = jni->CallObjectMethodA(
52 getJniInfo()->m_method_IEnvironment_getRegisteredInterface,
args );
55 if (jo_iface ==
nullptr)
59 m_uno_env,
reinterpret_cast< void **
>( &pUnoI ),
60 oid.pData,
reinterpret_cast<typelib_InterfaceTypeDescription *
>(info->
m_td.get()) );
65 args2[ 0 ].j =
reinterpret_cast< sal_Int64
>( this );
66 (*pUnoI->acquire)( pUnoI );
68 args2[ 2 ].j =
reinterpret_cast< sal_Int64
>( pUnoI );
70 args2[ 3 ].j =
reinterpret_cast< sal_Int64
>( info->
m_td.get() );
71 args2[ 4 ].l = info->
m_type;
72 args2[ 5 ].l = jo_oid.
get();
77 std::unique_lock g(envData->mutex);
78 args2[ 7 ].l = envData->asynchronousFinalizer;
80 jo_iface = jni->CallStaticObjectMethodA(
82 getJniInfo()->m_method_JNI_proxy_create, args2 );
86 assert( jo_iface !=
nullptr );
93 if (uno_exc->pType->eTypeClass == typelib_TypeClass_EXCEPTION)
95#if OSL_DEBUG_LEVEL > 0
97 static_cast< css::uno::Exception *
>(
102 "exception occurred java->uno: ["
103 << OUString::unacquired(&uno_exc->pType->pTypeName) <<
"] "
104 <<
static_cast<css::uno::Exception
const *
>(
105 uno_exc->pData)->Message);
111 jni, &java_exc, uno_exc->pData, uno_exc->pType,
nullptr,
122 jint res = jni->Throw(
static_cast<jthrowable
>(jo_exc.
get()) );
127 jni, jni->CallObjectMethodA(
128 jo_exc.
get(),
getJniInfo()->m_method_Object_toString,
nullptr ) );
131 "throwing java exception failed: "
139 "thrown exception is no uno exception: " +
140 OUString::unacquired( &uno_exc->pType->pTypeName ) +
162 typelib_TypeDescriptionReference * return_type,
163 sal_Int32 nParams, typelib_MethodParameter
const * pParams,
164 jobjectArray jo_args )
const
167 sal_Int32 return_size;
168 switch (return_type->eTypeClass) {
169 case typelib_TypeClass_VOID:
173 case typelib_TypeClass_STRUCT:
174 case typelib_TypeClass_EXCEPTION:
175 return_size = std::max(
177 static_cast< sal_Int32
>(
sizeof (largest)));
181 return_size =
sizeof (largest);
185 char * mem =
static_cast<char *
>(alloca(
186 (nParams *
sizeof (
void *)) +
187 return_size + (nParams *
sizeof (largest)) ));
188 void ** uno_args =
reinterpret_cast<void **
>(mem);
189 void * uno_ret = return_size == 0 ? nullptr : (mem + (nParams *
sizeof (
void *)));
190 largest * uno_args_mem =
reinterpret_cast<largest *
>
191 (mem + (nParams *
sizeof (
void *)) + return_size);
193 assert( (nParams == 0) || (nParams == jni->GetArrayLength( jo_args )) );
196 typelib_MethodParameter
const & param = pParams[
nPos ];
197 typelib_TypeDescriptionReference *
type = param.pTypeRef;
199 uno_args[
nPos ] = &uno_args_mem[
nPos ];
200 if (
type->eTypeClass == typelib_TypeClass_STRUCT ||
201 type->eTypeClass == typelib_TypeClass_EXCEPTION)
204 if (sal::static_int_cast< sal_uInt32 >(td.
get()->nSize)
206 uno_args[
nPos ] = alloca( td.
get()->nSize );
214 jni, jni->GetObjectArrayElement( jo_args,
nPos ) );
217 java_arg.l = jo_arg.
get();
219 jni, uno_args[
nPos ], java_arg,
type,
nullptr,
226 for ( sal_Int32
n = 0;
n <
nPos; ++
n )
228 typelib_MethodParameter
const &
p = pParams[
n ];
232 uno_args[
n ],
p.pTypeRef,
nullptr );
241 uno_Any * uno_exc = &uno_exc_holder;
243 (*pUnoI->pDispatcher)( pUnoI, member_td, uno_ret, uno_args, &uno_exc );
245 if (uno_exc ==
nullptr)
250 typelib_MethodParameter
const & param = pParams[
nPos ];
251 typelib_TypeDescriptionReference *
type = param.pTypeRef;
258 jni, jni->GetObjectArrayElement( jo_args,
nPos ) );
261 java_arg.l = jo_out_holder.
get();
263 jni, &java_arg, uno_args[
nPos ],
type,
nullptr,
269 for ( sal_Int32
n =
nPos;
n < nParams; ++
n )
272 uno_args[
n ], pParams[
n ].pTypeRef,
nullptr );
279 if (typelib_TypeClass_DOUBLE < type->eTypeClass &&
280 type->eTypeClass != typelib_TypeClass_ENUM)
286 if (return_type->eTypeClass != typelib_TypeClass_VOID)
293 jni, &java_ret, uno_ret, return_type,
nullptr,
302 if (typelib_TypeClass_DOUBLE < return_type->eTypeClass &&
303 return_type->eTypeClass != typelib_TypeClass_ENUM)
316 typelib_MethodParameter
const & param = pParams[
nPos ];
334SAL_JNI_EXPORT jobject
336 JNIEnv * jni_env, jobject jo_proxy, jlong bridge_handle, jstring jo_method,
337 jobjectArray jo_args )
339 Bridge
const * bridge =
reinterpret_cast< Bridge
const *
>( bridge_handle );
340 JNI_info
const * jni_info = bridge->getJniInfo();
343 static_cast< jobject
>(
344 static_cast<JniUnoEnvironmentData *
>(bridge->m_java_env->pContext)
345 ->machine->getClassLoader()));
347 OUString method_name;
351 method_name = jstring_to_oustring( jni, jo_method );
354 "java->uno call: " << method_name <<
" on oid "
355 << jstring_to_oustring(
357 static_cast<jstring
>(
361 jo_proxy, jni_info->m_field_JNI_proxy_m_oid))
364 if ( method_name ==
"queryInterface" )
367 JLocalAutoRef jo_oid(
368 jni, jni->GetObjectField(
369 jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
371 JLocalAutoRef jo_type(
372 jni, jni->GetObjectArrayElement( jo_args, 0 ) );
373 jni.ensure_no_exception();
375 JLocalAutoRef jo_type_name(
376 jni, jni->GetObjectField(
377 jo_type.get(), jni_info->m_field_Type_typeName ) );
378 if (! jo_type_name.is())
381 "incomplete type object: no type name!" +
382 jni.get_stack_trace() );
385 jstring_to_oustring( jni,
static_cast<jstring
>(jo_type_name.get()) ) );
386 JNI_type_info
const * info =
387 jni_info->get_type_info( jni, type_name );
388 if (info->m_td.get()->eTypeClass != typelib_TypeClass_INTERFACE)
391 "queryInterface() call demands an INTERFACE type!" );
393 JNI_interface_type_info
const * iface_info =
394 static_cast< JNI_interface_type_info
const *
>( info );
398 uno_Interface * pUnoI =
reinterpret_cast< uno_Interface *
>(
400 jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
403 void * uno_args[] = { &iface_info->m_td.get()->pWeakRef };
405 uno_Any * uno_exc = &uno_exc_holder;
407 (*pUnoI->pDispatcher)(
408 pUnoI, jni_info->m_XInterface_queryInterface_td.get(),
409 &uno_ret, uno_args, &uno_exc );
410 if (uno_exc ==
nullptr)
412 jobject jo_ret =
nullptr;
413 if (uno_ret.pType->eTypeClass == typelib_TypeClass_INTERFACE)
415 uno_Interface * pUnoRet =
416 static_cast<uno_Interface *
>(uno_ret.pReserved);
417 if (pUnoRet !=
nullptr)
422 bridge->map_to_java( jni, pUnoRet, iface_info );
436 bridge->handle_uno_exc( jni, uno_exc );
441 typelib_InterfaceTypeDescription * td =
442 reinterpret_cast< typelib_InterfaceTypeDescription *
>(
444 jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) );
445 uno_Interface * pUnoI =
446 reinterpret_cast< uno_Interface *
>(
448 jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
450 typelib_TypeDescriptionReference ** ppAllMembers = td->ppAllMembers;
451 for ( sal_Int32
nPos = td->nAllMembers;
nPos--; )
456 typelib_TypeDescriptionReference * member_type =
457 ppAllMembers[
nPos ];
462 OUString
const & type_name =
463 OUString::unacquired( &member_type->pTypeName );
464 sal_Int32 offset = type_name.indexOf(
':' ) + 2;
466 assert(offset < type_name.getLength());
467 assert(type_name[offset - 1] ==
':' );
468 sal_Int32 remainder = type_name.getLength() - offset;
469 if (member_type->eTypeClass == typelib_TypeClass_INTERFACE_METHOD)
471 if ((method_name.getLength() == remainder
472 || (method_name.getLength() < remainder
473 && type_name[offset + method_name.getLength()] ==
':'))
474 && type_name.match(method_name, offset))
476 TypeDescr member_td( member_type );
477 typelib_InterfaceMethodTypeDescription * method_td =
479 typelib_InterfaceMethodTypeDescription *
>(
481 return bridge->call_uno(
482 jni, pUnoI, member_td.get(),
483 method_td->pReturnTypeRef,
484 method_td->nParams, method_td->pParams,
491 member_type->eTypeClass ==
492 typelib_TypeClass_INTERFACE_ATTRIBUTE );
494 if (method_name.getLength() >= 3
495 && (method_name.getLength() - 3 == remainder
496 || (method_name.getLength() - 3 < remainder
498 offset + (method_name.getLength() - 3)] ==
':'))
499 && method_name[1] ==
'e' && method_name[2] ==
't'
500 && rtl_ustr_compare_WithLength(
501 type_name.getStr() + offset,
502 method_name.getLength() - 3,
503 method_name.getStr() + 3,
504 method_name.getLength() - 3) == 0)
506 if (method_name[ 0 ] ==
'g')
508 TypeDescr member_td( member_type );
509 typelib_InterfaceAttributeTypeDescription * attr_td =
511 typelib_InterfaceAttributeTypeDescription *
>(
513 return bridge->call_uno(
514 jni, pUnoI, member_td.get(),
515 attr_td->pAttributeTypeRef,
519 else if (method_name[ 0 ] ==
's')
521 TypeDescr member_td( member_type );
522 typelib_InterfaceAttributeTypeDescription * attr_td =
524 typelib_InterfaceAttributeTypeDescription *
>(
526 if (! attr_td->bReadOnly)
528 typelib_MethodParameter param;
529 param.pTypeRef = attr_td->pAttributeTypeRef;
532 return bridge->call_uno(
533 jni, pUnoI, member_td.get(),
534 jni_info->m_void_type.getTypeLibType(),
544 "calling undeclared function on interface "
545 + OUString::unacquired(&td->aBase.pTypeName)
546 +
": " + method_name + jni.get_stack_trace() );
552 "Java calling UNO method " << method_name <<
": " <<
err.m_message);
555 "[jni_uno bridge error] Java calling UNO method "
558 if (jni->ThrowNew(jni_info->m_class_RuntimeException, cstr_msg.getStr())
565 catch (const ::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
567 SAL_WARN(
"bridges",
"attaching current thread to java failed");
569 "[jni_uno bridge error] attaching current thread to java failed"
571 jni.get_stack_trace(), RTL_TEXTENCODING_JAVA_UTF8));
572 if (jni->ThrowNew(jni_info->m_class_RuntimeException, cstr_msg.getStr())
584 JNIEnv * jni_env, jobject jo_proxy, jlong bridge_handle )
586 Bridge
const * bridge =
reinterpret_cast< Bridge
const *
>( bridge_handle );
587 JNI_info
const * jni_info = bridge->getJniInfo();
590 static_cast< jobject
>(
591 static_cast<JniUnoEnvironmentData *
>(bridge->m_java_env->pContext)
592 ->machine->getClassLoader()));
594 uno_Interface * pUnoI =
reinterpret_cast< uno_Interface *
>(
596 jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
600 jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) );
603 "freeing java uno proxy: "
604 << jstring_to_oustring(
606 static_cast<jstring
>(
610 jo_proxy, jni_info->m_field_JNI_proxy_m_oid))
613 (*bridge->m_uno_env->revokeInterface)( bridge->m_uno_env, pUnoI );
615 (*pUnoI->release)( pUnoI );
void SAL_CALL uno_any_destruct(uno_Any *pValue, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
OUString get_stack_trace(jobject jo_exc=nullptr) const
void ensure_no_exception() const
jobject m_object_java_env
typelib_TypeDescription * get() const
void SAL_CALL uno_type_destructData(void *pValue, typelib_TypeDescriptionReference *pType, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
SAL_JNI_EXPORT jobject JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch_1call(JNIEnv *jni_env, jobject jo_proxy, jlong bridge_handle, jstring jo_method, jobjectArray jo_args)
SAL_JNI_EXPORT void JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_finalize__J(JNIEnv *jni_env, jobject jo_proxy, jlong bridge_handle)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
struct _typelib_TypeDescription typelib_TypeDescription
OUString jstring_to_oustring(JNI_context const &jni, jstring jstr)
jstring ustring_to_jstring(JNI_context const &jni, rtl_uString const *ustr)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
void map_to_java(JNI_context const &jni, jvalue *java_data, void const *uno_data, typelib_TypeDescriptionReference *type, JNI_type_info const *info, bool in_param, bool out_param, bool special_wrapped_integral_types=false) const
void map_to_uno(JNI_context const &jni, void *uno_data, jvalue java_data, typelib_TypeDescriptionReference *type, JNI_type_info const *info, bool assign, bool out_param, bool special_wrapped_integral_types=false) const
uno_ExtEnvironment * m_uno_env
JNI_info const * getJniInfo() const
void handle_uno_exc(JNI_context const &jni, uno_Any *uno_exc) const
jobject call_uno(JNI_context const &jni, uno_Interface *pUnoI, typelib_TypeDescription *member_td, typelib_TypeDescriptionReference *return_tdref, sal_Int32 nParams, typelib_MethodParameter const *pParams, jobjectArray jo_args) const
uno_Environment * m_java_env
::com::sun::star::uno::TypeDescription m_td
void SAL_CALL typelib_typedescription_release(typelib_TypeDescription *pTD) SAL_THROW_EXTERN_C()
void SAL_CALL typelib_typedescription_acquire(typelib_TypeDescription *pTypeDescription) SAL_THROW_EXTERN_C()