1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_bridges.hxx" 26 #include <malloc.h> 27 #include <com/sun/star/uno/genfunc.hxx> 28 #include <uno/data.h> 29 30 #include "bridges/cpp_uno/shared/bridge.hxx" 31 #include "bridges/cpp_uno/shared/types.hxx" 32 #include "bridges/cpp_uno/shared/unointerfaceproxy.hxx" 33 #include "bridges/cpp_uno/shared/vtables.hxx" 34 35 #include "share.hxx" 36 37 using namespace rtl; 38 using namespace com::sun::star::uno; 39 40 namespace 41 { 42 //================================================================================================== 43 // The call instruction within the asm section of callVirtualMethod may throw 44 // exceptions. So that the compiler handles this correctly, it is important 45 // that (a) callVirtualMethod might call dummy_can_throw_anything (although this 46 // never happens at runtime), which in turn can throw exceptions, and (b) 47 // callVirtualMethod is not inlined at its call site (so that any exceptions are 48 // caught which are thrown from the instruction calling callVirtualMethod): 49 50 void callVirtualMethod( void * pAdjustedThisPtr, 51 sal_Int32 nVtableIndex, 52 void * pRegisterReturn, 53 typelib_TypeClass eReturnType, 54 sal_Int32 * pStackLongs, 55 sal_Int32 nStackLongs ) __attribute__((noinline)); 56 57 void callVirtualMethod( void * pAdjustedThisPtr, 58 sal_Int32 /* nVtableIndex */, 59 void * pRegisterReturn, 60 typelib_TypeClass eReturnType, 61 #if OSL_DEBUG_LEVEL > 0 62 sal_Int32 * pStackLongs, 63 sal_Int32 nStackLongs) 64 #else 65 sal_Int32 * /*pStackLongs*/, 66 sal_Int32 /*nStackLongs*/) 67 #endif 68 { 69 // parameter list is mixed list of * and values 70 // reference parameters are pointers 71 72 OSL_ENSURE( pStackLongs && pAdjustedThisPtr, "### null ptr!" ); 73 OSL_ENSURE( (sizeof(void *) == 4) && 74 (sizeof(sal_Int32) == 4), "### unexpected size of int!" ); 75 OSL_ENSURE( nStackLongs && pStackLongs, "### no stack in callVirtualMethod !" ); 76 77 // never called 78 if (! pAdjustedThisPtr) CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something 79 80 volatile long o0 = 0, o1 = 0; // for register returns 81 volatile double f0d = 0; 82 volatile float f0f = 0; 83 volatile long long saveReg[7]; 84 85 __asm__ ( 86 // save registers 87 "std %%l0, [%4]\n\t" 88 "mov %4, %%l0\n\t" 89 "mov %%l0, %%l1\n\t" 90 "add %%l0, 8, %%l0\n\t" 91 "std %%l2, [%%l0]\n\t" 92 "add %%l0, 8, %%l0\n\t" 93 "std %%l4, [%%l0]\n\t" 94 "add %%l0, 8, %%l0\n\t" 95 "std %%o0, [%%l0]\n\t" 96 "add %%l0, 8, %%l0\n\t" 97 "std %%o2, [%%l0]\n\t" 98 "add %%l0, 8, %%l0\n\t" 99 "std %%o4, [%%l0]\n\t" 100 "add %%l0, 8, %%l0\n\t" 101 "std %%l6, [%%l0]\n\t" 102 "mov %%l1, %%l7\n\t" 103 104 // increase our own stackframe if necessary 105 "mov %%sp, %%l3\n\t" // save stack ptr for readjustment 106 107 "subcc %%i5, 7, %%l0\n\t" 108 "ble .LmoveOn\n\t" 109 "nop\n\t" 110 111 "sll %%l0, 2, %%l0\n\t" 112 "add %%l0, 96, %%l0\n\t" 113 "mov %%sp, %%l1\n\t" // old stack ptr 114 "sub %%sp, %%l0, %%l0\n\t" // future stack ptr 115 "andcc %%l0, 7, %%g0\n\t" // align stack to 8 116 "be .LisAligned\n\t" 117 "nop\n\t" 118 "sub %%l0, 4, %%l0\n" 119 ".LisAligned:\n\t" 120 "mov %%l0, %%o5\n\t" // save newly computed stack ptr 121 "add %%g0, 16, %%o4\n" 122 123 // now copy longs down to save register window 124 // and local variables 125 ".LcopyDown:\n\t" 126 "ld [%%l1], %%l2\n\t" 127 "st %%l2,[%%l0]\n\t" 128 "add %%l0, 4, %%l0\n\t" 129 "add %%l1, 4, %%l1\n\t" 130 "subcc %%o4, 1, %%o4\n\t" 131 "bne .LcopyDown\n\t" 132 133 "mov %%o5, %%sp\n\t" // move new stack ptr (hopefully) atomically 134 // while register window is valid in both spaces 135 // (scheduling might hit in copyDown loop) 136 137 "sub %%i5, 7, %%l0\n\t" // copy parameters past the sixth to stack 138 "add %%i4, 28, %%l1\n\t" 139 "add %%sp, 92, %%l2\n" 140 ".LcopyLong:\n\t" 141 "ld [%%l1], %%o0\n\t" 142 "st %%o0, [%%l2]\n\t" 143 "add %%l1, 4, %%l1\n\t" 144 "add %%l2, 4, %%l2\n\t" 145 "subcc %%l0, 1, %%l0\n\t" 146 "bne .LcopyLong\n\t" 147 "nop\n" 148 149 ".LmoveOn:\n\t" 150 "mov %%i5, %%l0\n\t" // prepare out registers 151 "mov %%i4, %%l1\n\t" 152 153 "ld [%%l1], %%o0\n\t" // prepare complex return ptr 154 "st %%o0, [%%sp+64]\n\t" 155 "sub %%l0, 1, %%l0\n\t" 156 "add %%l1, 4, %%l1\n\t" 157 158 "ld [%%l1], %%o0\n\t" 159 "subcc %%l0, 1, %%l0\n\t" 160 "be .LdoCall\n\t" 161 "nop\n\t" 162 163 "add %%l1, 4, %%l1\n\t" 164 "ld [%%l1], %%o1\n\t" 165 "subcc %%l0, 1, %%l0\n\t" 166 "be .LdoCall\n\t" 167 "nop\n\t" 168 169 "add %%l1, 4, %%l1\n\t" 170 "ld [%%l1], %%o2\n\t" 171 "subcc %%l0, 1, %%l0\n\t" 172 "be .LdoCall\n\t" 173 "nop\n\t" 174 175 "add %%l1, 4, %%l1\n\t" 176 "ld [%%l1], %%o3\n\t" 177 "subcc %%l0, 1, %%l0\n\t" 178 "be .LdoCall\n\t" 179 "nop\n\t" 180 181 "add %%l1, 4, %%l1\n\t" 182 "ld [%%l1], %%o4\n\t" 183 "subcc %%l0, 1, %%l0\n\t" 184 "be .LdoCall\n\t" 185 "nop\n\t" 186 187 "add %%l1, 4, %%l1\n\t" 188 "ld [%%l1], %%o5\n" 189 190 ".LdoCall:\n\t" 191 "ld [%%i0], %%l0\n\t" // get vtable ptr 192 193 "sll %%i1, 2, %%l6\n\t" 194 // "add %%l6, 8, %%l6\n\t" 195 "add %%l6, %%l0, %%l0\n\t" 196 // // vtable has 8byte wide entries, 197 // // upper half contains 2 half words, of which the first 198 // // is the this ptr patch ! 199 // // first entry is (or __tf) 200 201 // "ldsh [%%l0], %%l6\n\t" // load this ptr patch 202 // "add %%l6, %%o0, %%o0\n\t" // patch this ptr 203 204 // "add %%l0, 4, %%l0\n\t" // get virtual function ptr 205 "ld [%%l0], %%l0\n\t" 206 207 "ld [%%i4], %%l2\n\t" 208 "subcc %%l2, %%g0, %%l2\n\t" 209 "bne .LcomplexCall\n\t" 210 "nop\n\t" 211 "call %%l0\n\t" 212 "nop\n\t" 213 "ba .LcallReturned\n\t" 214 "nop\n" 215 ".LcomplexCall:\n\t" 216 "call %%l0\n\t" 217 "nop\n\t" 218 "unimp\n" 219 220 ".LcallReturned:\n\t" 221 "mov %%l3, %%sp\n\t" // readjust stack so that our locals are where they belong 222 "st %%o0, %0\n\t" // save possible return registers into our locals 223 "st %%o1, %1\n\t" 224 "std %%f0, %2\n\t" 225 "st %%f0, %3\n\t" 226 227 // restore registers 228 "ldd [%%l7], %%l0\n\t" 229 "add %%l7, 8, %%l7\n\t" 230 "ldd [%%l7], %%l2\n\t" 231 "add %%l7, 8, %%l7\n\t" 232 "ldd [%%l7], %%l4\n\t" 233 "add %%l7, 8, %%l7\n\t" 234 "ldd [%%l7], %%o0\n\t" 235 "add %%l7, 8, %%l7\n\t" 236 "ldd [%%l7], %%o2\n\t" 237 "add %%l7, 8, %%l7\n\t" 238 "ldd [%%l7], %%o4\n\t" 239 "add %%l7, 8, %%l7\n\t" 240 "ldd [%%l7], %%l6\n\t" 241 : : 242 "m"(o0), 243 "m"(o1), 244 "m"(f0d), 245 "m"(f0f), 246 "r"(&saveReg[0]) 247 ); 248 switch( eReturnType ) 249 { 250 case typelib_TypeClass_HYPER: 251 case typelib_TypeClass_UNSIGNED_HYPER: 252 ((long*)pRegisterReturn)[1] = o1; 253 case typelib_TypeClass_LONG: 254 case typelib_TypeClass_UNSIGNED_LONG: 255 case typelib_TypeClass_ENUM: 256 ((long*)pRegisterReturn)[0] = o0; 257 break; 258 case typelib_TypeClass_CHAR: 259 case typelib_TypeClass_SHORT: 260 case typelib_TypeClass_UNSIGNED_SHORT: 261 *(unsigned short*)pRegisterReturn = (unsigned short)o0; 262 break; 263 case typelib_TypeClass_BOOLEAN: 264 case typelib_TypeClass_BYTE: 265 *(unsigned char*)pRegisterReturn = (unsigned char)o0; 266 break; 267 case typelib_TypeClass_FLOAT: 268 *(float*)pRegisterReturn = f0f; 269 break; 270 case typelib_TypeClass_DOUBLE: 271 *(double*)pRegisterReturn = f0d; 272 break; 273 default: 274 break; 275 } 276 } 277 278 //================================================================================================= 279 static void cpp_call( 280 bridges::cpp_uno::shared::UnoInterfaceProxy * pThis, 281 bridges::cpp_uno::shared::VtableSlot aVtableSlot, 282 typelib_TypeDescriptionReference * pReturnTypeRef, 283 sal_Int32 nParams, typelib_MethodParameter * pParams, 284 void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc ) 285 { 286 // max space for: complex ret ptr, this, values|ptr ... 287 char * pCppStack = 288 (char *)alloca( (nParams+2) * sizeof(sal_Int64) ); 289 char * pCppStackStart = pCppStack; 290 291 // return 292 typelib_TypeDescription * pReturnTypeDescr = 0; 293 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef ); 294 OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" ); 295 296 void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion 297 298 if (pReturnTypeDescr) 299 { 300 if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr )) 301 { 302 pCppReturn = pUnoReturn; // direct way for simple types 303 *(void**)pCppStack = NULL; 304 } 305 else 306 { 307 // complex return via ptr 308 pCppReturn = *(void **)pCppStack = (bridges::cpp_uno::shared::relatesToInterfaceType(pReturnTypeDescr ) 309 ? alloca( pReturnTypeDescr->nSize ) 310 : pUnoReturn); // direct way 311 } 312 pCppStack += sizeof(void*); 313 } 314 // push this 315 void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI()) 316 + aVtableSlot.offset; 317 *(void**)pCppStack = pAdjustedThisPtr; 318 pCppStack += sizeof( void* ); 319 320 // stack space 321 OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" ); 322 // args 323 void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams ); 324 // indizes of values this have to be converted (interface conversion cpp<=>uno) 325 sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams); 326 // type descriptions for reconversions 327 typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams)); 328 329 sal_Int32 nTempIndizes = 0; 330 331 for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) 332 { 333 const typelib_MethodParameter & rParam = pParams[nPos]; 334 typelib_TypeDescription * pParamTypeDescr = 0; 335 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef ); 336 if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) 337 { 338 pCppArgs[ nPos ] = CPPU_CURRENT_NAMESPACE::adjustPointer(pCppStack, pParamTypeDescr ); 339 340 switch (pParamTypeDescr->eTypeClass) 341 { 342 case typelib_TypeClass_HYPER: 343 case typelib_TypeClass_UNSIGNED_HYPER: 344 case typelib_TypeClass_DOUBLE: 345 OSL_ASSERT( sizeof (double) == sizeof (sal_Int64) ); 346 *reinterpret_cast< sal_Int32 * >(pCppStack) = 347 *reinterpret_cast< sal_Int32 const * >(pUnoArgs[ nPos ]); 348 pCppStack += sizeof (sal_Int32); 349 *reinterpret_cast< sal_Int32 * >(pCppStack) = 350 *(reinterpret_cast< sal_Int32 const * >(pUnoArgs[ nPos ] ) + 1); 351 break; 352 default: 353 uno_copyAndConvertData( 354 pCppArgs[nPos], pUnoArgs[nPos], pParamTypeDescr, 355 pThis->getBridge()->getUno2Cpp() ); 356 break; 357 } 358 // no longer needed 359 TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 360 } 361 else // ptr to complex value | ref 362 { 363 if (! rParam.bIn) // is pure out 364 { 365 // cpp out is constructed mem, uno out is not! 366 uno_constructData( 367 *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ), 368 pParamTypeDescr ); 369 pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call 370 // will be released at reconversion 371 ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; 372 } 373 // is in/inout 374 else if (bridges::cpp_uno::shared::relatesToInterfaceType( 375 pParamTypeDescr )) 376 { 377 uno_copyAndConvertData( 378 *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ), 379 pUnoArgs[nPos], pParamTypeDescr, 380 pThis->getBridge()->getUno2Cpp() ); 381 382 pTempIndizes[nTempIndizes] = nPos; // has to be reconverted 383 // will be released at reconversion 384 ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; 385 } 386 else // direct way 387 { 388 *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos]; 389 // no longer needed 390 TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 391 } 392 } 393 pCppStack += sizeof(sal_Int32); // standard parameter length 394 } 395 396 try 397 { 398 int nStackLongs = (pCppStack - pCppStackStart)/sizeof(sal_Int32); 399 OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic" ); 400 401 if( nStackLongs & 1 ) 402 // stack has to be 8 byte aligned 403 nStackLongs++; 404 callVirtualMethod( 405 pAdjustedThisPtr, 406 aVtableSlot.index, 407 pCppReturn, 408 pReturnTypeDescr->eTypeClass, 409 (sal_Int32 *)pCppStackStart, 410 nStackLongs); 411 // NO exception occured... 412 *ppUnoExc = 0; 413 414 // reconvert temporary params 415 for ( ; nTempIndizes--; ) 416 { 417 sal_Int32 nIndex = pTempIndizes[nTempIndizes]; 418 typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes]; 419 420 if (pParams[nIndex].bIn) 421 { 422 if (pParams[nIndex].bOut) // inout 423 { 424 uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value 425 uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr, 426 pThis->getBridge()->getCpp2Uno() ); 427 } 428 } 429 else // pure out 430 { 431 uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr, 432 pThis->getBridge()->getCpp2Uno() ); 433 } 434 // destroy temp cpp param => cpp: every param was constructed 435 uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release ); 436 437 TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 438 } 439 // return value 440 if (pCppReturn && pUnoReturn != pCppReturn) 441 { 442 uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr, 443 pThis->getBridge()->getCpp2Uno() ); 444 uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release ); 445 } 446 } 447 catch( ... ) 448 { 449 // get exception 450 fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, 451 *ppUnoExc, pThis->getBridge()->getCpp2Uno() ); 452 453 // temporary params 454 for ( ; nTempIndizes--; ) 455 { 456 sal_Int32 nIndex = pTempIndizes[nTempIndizes]; 457 // destroy temp cpp param => cpp: every param was constructed 458 uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release ); 459 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] ); 460 } 461 // return type 462 if (pReturnTypeDescr) 463 TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); 464 } 465 } 466 467 } 468 469 namespace bridges { namespace cpp_uno { namespace shared { 470 471 void unoInterfaceProxyDispatch( 472 uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr, 473 void * pReturn, void * pArgs[], uno_Any ** ppException ) 474 { 475 #if defined BRIDGES_DEBUG 476 OString cstr( OUStringToOString( pMemberDescr->pTypeName, RTL_TEXTENCODING_ASCII_US ) ); 477 fprintf( stderr, "received dispatch( %s )\n", cstr.getStr() ); 478 #endif 479 480 // is my surrogate 481 bridges::cpp_uno::shared::UnoInterfaceProxy * pThis 482 = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI); 483 // typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr; 484 485 switch (pMemberDescr->eTypeClass) 486 { 487 case typelib_TypeClass_INTERFACE_ATTRIBUTE: 488 { 489 VtableSlot aVtableSlot( 490 getVtableSlot( 491 reinterpret_cast< 492 typelib_InterfaceAttributeTypeDescription const * >( 493 pMemberDescr))); 494 if (pReturn) 495 { 496 // dependent dispatch 497 cpp_call( 498 pThis, aVtableSlot, 499 ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef, 500 0, 0, // no params 501 pReturn, pArgs, ppException ); 502 } 503 else 504 { 505 // is SET 506 typelib_MethodParameter aParam; 507 aParam.pTypeRef = 508 ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef; 509 aParam.bIn = sal_True; 510 aParam.bOut = sal_False; 511 512 typelib_TypeDescriptionReference * pReturnTypeRef = 0; 513 OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") ); 514 typelib_typedescriptionreference_new( 515 &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData ); 516 517 // dependent dispatch 518 aVtableSlot.index += 1; // get, then set method 519 cpp_call( 520 pThis, aVtableSlot, 521 pReturnTypeRef, 522 1, &aParam, 523 pReturn, pArgs, ppException ); 524 525 typelib_typedescriptionreference_release( pReturnTypeRef ); 526 } 527 528 break; 529 } 530 case typelib_TypeClass_INTERFACE_METHOD: 531 { 532 VtableSlot aVtableSlot( 533 getVtableSlot( 534 reinterpret_cast< 535 typelib_InterfaceMethodTypeDescription const * >( 536 pMemberDescr))); 537 switch (aVtableSlot.index) 538 { 539 // standard calls 540 case 1: // acquire uno interface 541 (*pUnoI->acquire)( pUnoI ); 542 *ppException = 0; 543 break; 544 case 2: // release uno interface 545 (*pUnoI->release)( pUnoI ); 546 *ppException = 0; 547 break; 548 case 0: // queryInterface() opt 549 { 550 typelib_TypeDescription * pTD = 0; 551 TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() ); 552 if (pTD) 553 { 554 uno_Interface * pInterface = 0; 555 (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)( 556 pThis->pBridge->getUnoEnv(), 557 (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD ); 558 559 if (pInterface) 560 { 561 ::uno_any_construct( 562 reinterpret_cast< uno_Any * >( pReturn ), 563 &pInterface, pTD, 0 ); 564 (*pInterface->release)( pInterface ); 565 TYPELIB_DANGER_RELEASE( pTD ); 566 *ppException = 0; 567 break; 568 } 569 TYPELIB_DANGER_RELEASE( pTD ); 570 } 571 } // else perform queryInterface() 572 default: 573 // dependent dispatch 574 cpp_call( 575 pThis, aVtableSlot, 576 ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef, 577 ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams, 578 ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams, 579 pReturn, pArgs, ppException ); 580 } 581 break; 582 } 583 default: 584 { 585 ::com::sun::star::uno::RuntimeException aExc( 586 OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ), 587 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() ); 588 589 Type const & rExcType = ::getCppuType( &aExc ); 590 // binary identical null reference 591 ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 ); 592 } 593 } 594 } 595 596 } } } 597