このページはEtoJ逐語翻訳フィルタによって翻訳生成されました。

翻訳前ページへ


null
Language

The 解放する/自由な and Open 生産性 控訴
解放(する)d: Apache OpenOffice 4.1.16
器具/実施するing an C++ - UNO 橋(渡しをする)

器具/実施するing a C++ - UNO 橋(渡しをする)

OpenOffice.org

Contents

客観的な
Terminology
負担ing a 橋(渡しをする)
環境
Mapping
Microsoft Visual C++ - UNO 橋(渡しをする)

客観的な

This 文書 is written for developers 器具/実施するing a 橋(渡しをする) from C++ to binary UNO. The last paragraph covers the Microsoft Visual C++ - UNO 橋(渡しをする) in 詳細(に述べる).

Terminology

負担ing a 橋(渡しをする)

Each 橋(渡しをする) is 器具/実施するd in a separate 株d library 負担d by the UNO runtime. The 指名するing 計画/陰謀 of the library is a concatenation with the に引き続いて:

[purpose_]SourceEnvName_DestEnvName

The optional 目的 denotes the 目的 of the 橋(渡しをする), e.g. 議定書 traffic between two 環境s. If no 目的 is given, then the 橋(渡しをする) just 地図/計画するs interfaces from source to 目的地 環境.

Windows examples: prot_uno_uno.dll, msci_uno.dll
Solaris examples: libprot_uno_uno.so, libsunpro5_uno.so

The 橋(渡しをする) library 輸出(する)s two 機能(する)/行事s called uno_ext_getMapping() and uno_initEnvironment(). The latter is 現在/一般に 器具/実施するd by the 橋(渡しをする) library for pragmatic 推論する/理由s. The runtime will lookup an initialization library of an 環境 by 負担ing a library with 指名する EnvName_uno. uno_getEnvironment() initializes the 環境, e.g. raises the JVM, 始める,決めるs a 配置する/処分する/したい気持ちにさせるing callback etc. C++ 環境s usually do nothing.

無効の SAL_CALL uno_initEnvironment(
    uno_Environment * pEnv ); 

The first 機能(する)/行事, uno_ext_getMapping(), is called by the UNO runtime to get the mappings for both directions. The uno_ext_getMapping() call receives a source and 目的地 環境 扱う to distinguish which mapping is 需要・要求するd. It is やめる (疑いを)晴らす that the 橋(渡しをする) library cannot be 荷を降ろすd while any code of it is still needed, i.e. interfaces are held. So both mappings and any wrapped interface (proxy) that is 輸出(する)d needs to 修正する a 株d library wide 言及/関連 count.

無効の SAL_CALL uno_ext_getMapping(
    uno_Mapping ** ppMapping,
    uno_Environment * pFrom, uno_Environment * pTo );

環境

The 意向 of an 環境 (and programmatically 環境 扱うs) is to identify (given by its type 指名する and 状況 pointer) and optionally to 供給する extra functionality like interface 登録.

In 明確な/細部 the latter point is very important, because of the 反対する 身元 of an interface. Any UNO 反対する is defined to 供給する the same instance of XInterface any time it is queried for it. This specification has been made to 実験(する) whether two interfaces belong to the same 反対する (e.g. when 実験(する)ing the source 反対する of an 後継の event). So when interfaces are mapped around to some 環境s outer space, they must 供給する the same XInterface in each 環境 (e.g. in C++, equal XInterface pointers).

Also it is recommended to 再使用する any interface you can, i.e. 減ずるing the construction of proxy interfaces as often as you can, because each 建設するd proxy interface leads の中で the 取得/買収 of 資源s to another indirection when called.

The structure of an 環境 is 分裂(する) into the simple ありふれた "身元" part which can easily be 器具/実施するd by 橋(渡しをする)s that 扱う 反対する 身元 問題/発行するs in their own way. If the 環境 実施 supports interface 登録 functionality etc. then the optional pointer is 始める,決める. Optional functionality is interface 登録, acquiring/ 解放(する)ing interfaces of the 環境 and 得るing 反対する identifiers for an interface.

Interface 登録 is divided into 登録 of proxy and 初めの interfaces. 明白に proxies have to be held unacquired, さもなければ mapped interfaces will never die. The 支配する for a 言及/関連 counted C++ proxy is, that it 登録(する)s itself when 言及/関連 count increments from 0 to 1 and 取り消すs itself when the count decrements from 1 to 0. To synchronize 登録 接近 while not 認めるing 内部の locks on the interface 登録, the proxy will be explicitly 解放する/自由なd by the 環境 by its given freeProxy() 機能(する)/行事 at 登録.

/** The binary specification of an UNO 環境. */
typedef struct _uno_Environment
{
    /** reserved for 未来 use (0 if not used)
    */
    無効の *               pReserved;
    
    /** type 指名する of 環境
    */
    rtl_uString *        pTypeName;
    
    /** 解放する/自由な 状況 pointer to be used for 明確な/細部 classes of 環境s (e.g., a JVM pointer)
    */
    無効の *               pContext;
    
    /** pointer to 延長するd 環境 (interface 登録 functionality), if supported
    */
    uno_ExtEnvironment * pExtEnv;
    
    /** Acquires this 環境.
        @param pEnv this 環境
    */
    無効の (SAL_CALL * acquire)( uno_Environment * pEnv );
    
    /** 解放(する)s this 環境;
        last 解放(する) of 環境 will 取り消す the 環境 from runtime.
        @param pEnv this 環境
    */
    無効の (SAL_CALL * 解放(する))( uno_Environment * pEnv );
    
    /** Call this 機能(する)/行事 to explicitly 配置する/処分する/したい気持ちにさせる this 環境
        (e.g., 解放(する) all interfaces).
	You might want to call this 機能(する)/行事 before shutting 負かす/撃墜する 予定 to a runtime error.
	@param pEnv this 環境
    */
    無効の (SAL_CALL * 配置する/処分する/したい気持ちにさせる)( uno_Environment * pEnv );
    
    /* ===== the に引き続いて part will be late initialized by a matching 橋(渡しをする) ===== *
     * ===== and is NOT for public use.                                       ===== */
    
    /** CALLBACK
        配置する/処分する/したい気持ちにさせるing callback 機能(する)/行事 pointer that can be 始める,決める to get signalled before the 環境
        is destroyed.
	@param pEnv 環境 that is 存在 性質の/したい気がして
    */
    無効の (SAL_CALL * environmentDisposing)( uno_Environment * pEnv );
} uno_Environment;

/** Generic 機能(する)/行事 pointer 宣言 to 解放する/自由な a proxy 反対する if it is not needed
    by the 環境 anymore.
    Any proxy 反対する must 登録(する) itself on first acquire() call and 取り消す
    itself on last 解放(する)() call.
    This can happen several times because the 環境 (武器などの)隠匿場所s proxy 反対するs
    until the 環境 explicitly 解放する/自由なs the proxy 反対する calling this 機能(する)/行事.
    @param pEnv 環境
    @param pProxy proxy pointer
*/
typedef 無効の (SAL_CALL * uno_freeProxyFunc)( uno_ExtEnvironment * pEnv, 無効の * pProxy );

/** Generic 機能(する)/行事 pointer 宣言 to 配分する memory. Used with getRegisteredInterfaces().
    @param nBytes 量 of memory in bytes
    @return pointer to 配分するd memory
*/
typedef 無効の * (SAL_CALL * uno_memAlloc)( sal_uInt32 nBytes );

/** The binary specification of an UNO 環境 supporting interface 登録.
*/
typedef struct _uno_ExtEnvironment
{
    /** 相続するs all members of an uno_Environment
    */
    uno_Environment aBase;
    
    /** 登録(する)s an interface of this 環境.
        @param pEnv            this 環境
        @param ppInterface     inout parameter of interface to be 登録(する)d
        @param pOId            反対する id of interface
        @param pTypeDescr      type description of interface
    */
    無効の (SAL_CALL * registerInterface)(
        uno_ExtEnvironment * pEnv,
        無効の ** ppInterface,
        rtl_uString * pOId,
        typelib_InterfaceTypeDescription * pTypeDescr );
    
    /** 登録(する)s a proxy interface of this 環境 that can be reanimated and is
        解放する/自由なd explicitly by this 環境.
	@param pEnv            this 環境
        @param ppInterface     inout parameter of interface to be 登録(する)d
        @param freeProxy       機能(する)/行事 to 解放する/自由な proxy 反対する
        @param pOId            反対する id of interface
        @param pTypeDescr      type description of interface
    */
    無効の (SAL_CALL * registerProxyInterface)(
        uno_ExtEnvironment * pEnv,
        無効の ** ppProxy,
        uno_freeProxyFunc freeProxy,
        rtl_uString * pOId,
        typelib_InterfaceTypeDescription * pTypeDescr );
    
    /** 取り消すs an interface from this 環境.
        You have to 取り消す any interface that has been 登録(する)d 経由で this method.
	@param pEnv            this 環境
        @param pInterface      interface to be 取り消すd
    */
    無効の (SAL_CALL * revokeInterface)(
        uno_ExtEnvironment * pEnv,
        無効の * pInterface );
    
    /** 供給するs the 反対する id of a given interface.
        @param ppOut         inout oid
        @param pInterface    interface of 反対する
    */
    無効の (SAL_CALL * getObjectIdentifier)(
        uno_ExtEnvironment * pEnv,
        rtl_uString ** ppOId,
        無効の * pInterface );
    
    /** Retrieves an interface identified by its 反対する id and type from this 環境.
        Interfaces are retrieved in the same order as they are 登録(する)d.
	@param pEnv            this 環境
        @param ppInterface     inout parameter for the 登録(する)d interface; (0) if 非,不,無 was 設立する
        @param pOId            反対する id of interface to be retrieved
        @param pTypeDescr      type description of interface to be retrieved
    */
    無効の (SAL_CALL * getRegisteredInterface)(
        uno_ExtEnvironment * pEnv,
        無効の ** ppInterface,
        rtl_uString * pOId,
        typelib_InterfaceTypeDescription * pTypeDescr );
    
    /** Returns all 現在/一般に 登録(する)d interfaces of this 環境.
        The memory 封鎖する 配分するd might be わずかに larger than (*pnLen * sizeof(無効の *)).
	@param pEnv            this 環境
        @param pppInterfaces   out param; pointer to array of interface pointers
        @param pnLen           out param; length of array
        @param memAlloc        機能(する)/行事 for 配分するing memory that is passed 支援する
    */
    無効の (SAL_CALL * getRegisteredInterfaces)(
        uno_ExtEnvironment * pEnv,
        無効の *** pppInterfaces,
        sal_Int32 * pnLen,
        uno_memAlloc memAlloc );
    
    
    /* ===== the に引き続いて part will be late initialized by a matching 橋(渡しをする) ===== *
     * ===== and is NOT for public use.                                       ===== */
    
    /** 計算するs an 反対する id of the given interface; is called by the 環境
        実施.
	@param pEnv            corresponding 環境
        @param ppOId           out param: 計算するd id
        @param pInterface      an interface
    */
    無効の (SAL_CALL * computeObjectIdentifier)(
        uno_ExtEnvironment * pEnv,
        rtl_uString ** ppOId, 無効の * pInterface );
    
    /** 機能(する)/行事 to acquire an interface.
        @param pEnv            corresponding 環境
        @param pInterface      an interface
    */
    無効の (SAL_CALL * acquireInterface)( uno_ExtEnvironment * pEnv, 無効の * pInterface );
    
    /** 機能(する)/行事 to 解放(する) an interface.
        @param pEnv            corresponding 環境
        @param pInterface      an interface
    */
    無効の (SAL_CALL * releaseInterface)( uno_ExtEnvironment * pEnv, 無効の * pInterface );
} uno_ExtEnvironment;

There is a distinction between 登録(する)d 環境s and 匿名の/不明の 環境s. You can 得る an 存在するing 環境 by calling uno_getEnvironment(). If there is no 存在するing one, then uno_getEnvironment() creates and 登録(する)s a default one 供給するing the 付加 functionality (interface 登録 etc.). This is the ありふれた way.

In contrast to this you can call uno_createEnvironent() to create an 匿名の/不明の 環境 giving an 環境's type 指名する (e.g. "msci") and a 状況 pointer. Creating 匿名の/不明の 環境s is sensible if you need more than one 環境 of the same type. You may want to 議定書 any calls from/ to your 構成要素 and one 可能性 is the に引き続いて approach:

  1. Create an 匿名の/不明の 環境 of type "uno".
  2. Connect the 登録(する)d uno 環境 and the 匿名の/不明の 環境 経由で the 議定書 橋(渡しをする) "prot_uno_uno".
  3. Connect the 匿名の/不明の UNO 環境 with the 環境 of your 構成要素 using the C++ 橋(渡しをする) of choice (compiler that 収集するd the 構成要素 code).
  4. Connect your 開始する,打ち上げるing 環境 (the 環境 from within calls are put) with the 登録(する)d uno 環境.
  5. 開始する,打ち上げる your 構成要素.

Mapping

A 橋(渡しをする) consists of two mappings. Each mapping is 扶養家族 on its 相当するもの mapping, because 成し遂げるing a call may bring up the need to 変える interfaces from one 環境 to the other (e.g., in parameter interface) and 副/悪徳行為 versa (e.g., return values).

Mapping an interface from 環境 A to 環境 B 伴う/関わるs several steps to keep 跡をつける of 反対する 身元s:

  1. First the 反対する identifier of an interface is 決定するd by calling getObjectIdentifier() of 環境 A (source 環境).
  2. Then the 目的地 環境 is asked with the 反対する identifier and type, if there is a already a 登録(する)d interface in use. If this is the 事例/患者 you can use that one and 結局最後にはーなる here.
  3. If there is no such interface in use, the 橋(渡しをする) will produce a proxy of that type 委任する/代表ing all calls to the given source interface of 環境 A.
  4. The source interface will be 登録(する)d at 環境 A and the proxy interface will be introduced as a new proxy at 環境 B (registerProxyInterface()).

The whole シナリオ is shown in the big picture.

Microsoft Visual C++ - UNO 橋(渡しをする)

This is a short, source code based description of an UNO 橋(渡しをする) 実施 for C++ 反対するs 収集するd with the Microsoft Visual C++ 4-6. It covers the rudimentary calling stuff which is very 類似の to other compilers but omits exception 扱うing.

Mapping

Mapping an interface from one 環境 to another is transparently done 経由で the 権利 mapping, e.g. like the に引き続いて XFoo interface from UNO to the Microsoft Visual C++ 環境:

Mapping aMapping( "uno", "msci" );
XFoo * pFoo = (XFoo *)aMapping.mapInterface(
    pUnoFoo, ::getCppuType( (const 言及/関連< XFoo > *)0 ) );
...
pFoo->妨げる/法廷,弁護士業();
...
pFoo->解放(する)();

The given UNO interface is mapped to the Microsoft world transparently, so you can call methods and catch exceptions as if the calls are 成し遂げるd on an "初めの" Visual C++ 反対する.

To (人命などを)奪う,主張する this goal, the underlying 橋(渡しをする) has to emulate the behaviour and keep the 訂正する 反対する layout of its compiler. This example explains the 橋(渡しをする) from the Microsoft Visual C++ compiler to the binary (C-) UNO specification which is system 扶養家族, but not compiler 扶養家族. You can communicate with UNO 反対するs 収集するd with another compiler just by having an appropriate 橋(渡しをする) to UNO.

C++ Proxy

Under the hood the call 妨げる/法廷,弁護士業() that is 成し遂げるd on the mapped interface will call on a proxy C++ 反対する that 委任する/代表s the call to its corresponding UNO interface (the one given to mapInterface()). To create a C++ proxy, there is already a proxy class you can 修正する for your needs (header とじ込み/提出する 橋(渡しをする)s/inc/cpp_uno/橋(渡しをする).h). You usually instantiate this class and 修正する the vtable pointer, giving your generic vtable. For Microsoft Visual C++ you can use a generic one, because the 反対するs' this pointer is anytime the second stack parameter. On gcc or sunpro5 the first parameter may be the pointer to a struct return space. So for those compilers you have to 生成するd a vtable for each type that is used.

When the proxy interface is called, the vtable 索引 is 決定するd by the generic vtable and based on this, the method type description. This is the (警察などへの)密告,告訴(状) to get the values from the 加工業者 call stack and 成し遂げる a 派遣(する) call on the 的 UNO interface that the C++ proxy is wrapping.

After the 派遣(する) call has been done, the returned exception (警察などへの)密告,告訴(状) is checked whether a C++ exception has to be 生成するd and raised. If no exception has occurred, the inout/ out parameters have to be reconverted (which is only important for values 代表するing interfaces or values 含む/封じ込めるing interfaces though, because all UNO values are binary 両立できる on a 明確な/細部 計算するing architecture).

The C++ proxy 反対する 持つ/拘留するs the interface origin (i.e. the 的 uno interface) so it can 登録(する) itself at the 環境 on its first acquire() and 取り消す itself on its last 解放(する)() from its 環境.

struct cppu_cppInterfaceProxy : public ::com::sun::星/主役にする::uno::XInterface
{
    oslInterlockedCount                  nRef;
    cppu_Bridge *                        pBridge;
    
    // mapping (警察などへの)密告,告訴(状)
    uno_Interface *                      pUnoI; // wrapped interface
    typelib_InterfaceTypeDescription *   pTypeDescr;
    ::rtl::OUString                      oid;
    
    // 非,不,無 事実上の methods called on 後継の vtable calls #1, #2
    inline 無効の SAL_CALL acquireProxy();
    inline 無効の SAL_CALL releaseProxy();
    
    // XInterface: these are only here for 模造の, there will be a patched vtable!
    事実上の ::com::sun::星/主役にする::uno::Any SAL_CALL queryInterface(
        const ::com::sun::星/主役にする::uno::Type & )
        { return ::com::sun::星/主役にする::uno::Any(); } // don't use this, use cppu_queryInterface()!
    事実上の 無効の SAL_CALL acquire() {} // don't use this, use cppu_acquire()!
    事実上の 無効の SAL_CALL 解放(する)() {} // don't use this, use cppu_release()!
    
    // ctor
    inline cppu_cppInterfaceProxy( cppu_Bridge * pBridge_,
                                   uno_Interface * pUnoI_,
                                   typelib_InterfaceTypeDescription * pTypeDescr_,
                                   const ::rtl::OUString & rOId_ );
};

The proxy manages its 言及/関連 count, a pointer to its 橋(渡しをする) to get the 相当するもの mapping, the uno interface it 委任する/代表s calls to, the (interface) type it is emulating and an 反対する identifier (oid).

The type and 反対する identifier are needed to manage 反対するs from several 環境s and 証明する for 反対する 身元 and to 改善する 業績/成果 (no new interface is needed if there is already a 登録(する)d interface in the 環境).

Essentially if a proxy 反対する is created by the Visual C++ compiler, its vtable is patched, which is the very first pointer in the 反対する layout:

無効の SAL_CALL cppu_cppInterfaceProxy_patchVtable(
    XInterface * pCppI, typelib_InterfaceTypeDescription * pTypeDescr )
{
    static MediateVtables * s_pMediateVtables = 0;
    if (! s_pMediateVtables)
    {
        MutexGuard aGuard( Mutex::getGlobalMutex() );
        if (! s_pMediateVtables)
        {
            static MediateVtables s_aMediateVtables;
            s_pMediateVtables = &s_aMediateVtables;
        }
    }
    // nMapFunctionIndexToMemberIndex: 最小限 size of 需要・要求するd vtable
    *(const 無効の **)pCppI = s_pMediateVtables->getMediateVtable(
        pTypeDescr->nMapFunctionIndexToMemberIndex );
}

The call stack of a 事実上の 機能(する)/行事 call looks like this:

相殺する:

Value:

0

return 演説(する)/住所

4

this pointer

[if struct] 8

[if struct] pointer to return struct

8 | 12

parameter 0

...

...

The proxy vtable (i.e. 機能(する)/行事 pointer array to 成し遂げる polymorphic calls on C++ 反対するs) 決定するs which 機能(する)/行事 should be called (there is an 初期の vtable of 256 機能(する)/行事 slots that is used for any proxy while no proxy 需要・要求するs a larger one):

相殺する:

機能(する)/行事 pointer:

0

queryInterface() (XInterface member)

4

acquire() (XInterface member)

8

解放(する)() (XInterface member)

12

妨げる/法廷,弁護士業() (XFoo member)

...

...

The only 仕事 of the proxy vtable for Visual C++ is to 決定する the call 索引 of the uno method that is to be called, so the proxy vtable looks like:

相殺する:

機能(する)/行事 pointer to code:

0

mov eax, 0
jmp cpp_vtable_call

4

mov eax, 1
jmp cpp_vtable_call

8

mov eax, 2
jmp cpp_vtable_call

...

...

First the 妨げる/法廷,弁護士業() call reaches the assembler snippet which 決定するs the vtable slot and jumps to a 機能(する)/行事 called cpp_vtable_call():

/**
 * is called on 後継の vtable calls
 * (called by asm snippets)
 */
static __declspec(naked) 無効の __cdecl cpp_vtable_call(無効の)
{
__asm
    {
        sub        esp, 8         // space for 即座の return type
        押し進める       esp
        押し進める       eax            // vtable 索引
        mov        eax, esp
        追加する        eax, 16
        押し進める       eax            // 初めの stack ptr

        call       cpp_mediate
        追加する        esp, 12

        cmp        eax, typelib_TypeClass_FLOAT
        je         Lfloat
        cmp        eax, typelib_TypeClass_DOUBLE
        je         Ldouble
        cmp        eax, typelib_TypeClass_HYPER
        je         Lhyper
        cmp        eax, typelib_TypeClass_UNSIGNED_HYPER
        je         Lhyper
        // 残り/休憩(する) is eax
        pop        eax
        追加する        esp, 4
        ret
Lhyper:
        pop        eax
        pop        edx
        ret
Lfloat:
        fld        dword ptr [esp]
        追加する        esp, 8
        ret
Ldouble:
        fld        qword ptr [esp]
        追加する        esp, 8
        ret
    }
}

The cpp_vtable_call() 機能(する)/行事 just calls cpp_mediate() 供給するing some space for return values returned in 登録(する)s, the vtable slot and 初めの stack pointer. The cpp_mediate() 機能(する)/行事 returns the type class of the return value in eax. The type class is used to 決定する where to place return values.

static typelib_TypeClass __cdecl cpp_mediate(
    無効の ** pCallStack, sal_Int32 nVtableCall,
    sal_Int64 * pRegisterReturn /* space for 登録(する) return */ )
{
    OSL_ENSHURE( sizeof(sal_Int32)==sizeof(無効の *), "### 予期しない!" );
    
    // pCallStack: ret adr, this, [ret *], params
    // _this_ ptr is patched cppu_XInterfaceProxy 反対する
    cppu_cppInterfaceProxy * pThis = static_cast< cppu_cppInterfaceProxy * >(
        reinterpret_cast< XInterface * >( pCallStack[1] ) );
    
    typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
    OSL_ENSHURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex,
                 "### 違法な vtable 索引!" );
    if (nVtableCall >= pTypeDescr->nMapFunctionIndexToMemberIndex)
    {
        throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("違法な vtable 索引!") ),
                                (XInterface *)pThis );
    }
    
    // 決定する called method
    sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nVtableCall];
    OSL_ENSHURE( nMemberPos < pTypeDescr->nAllMembers, "### 違法な member 索引!" );

    TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );

    typelib_TypeClass eRet;
    switch (aMemberDescr.get()->eTypeClass)
    {
    事例/患者 typelib_TypeClass_INTERFACE_ATTRIBUTE:
    {
        if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nVtableCall)
        {
            // is GET method
            eRet = cpp2uno_call(
                pThis, aMemberDescr.get(),
                ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
                0, 0, // no params
                pCallStack, pRegisterReturn );
        }
        else
        {
            // is SET method
            typelib_MethodParameter aParam;
            aParam.pTypeRef =
                ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
            aParam.bIn        = sal_True;
            aParam.bOut        = sal_False;
            
            eRet = cpp2uno_call(
                pThis, aMemberDescr.get(),
                0, // 示すs 無効の return
                1, &aParam,
                pCallStack, pRegisterReturn );
        }
        break;
    }
    事例/患者 typelib_TypeClass_INTERFACE_METHOD:
    {
        // is METHOD
        switch (nVtableCall)
        {
            // 基準 XInterface vtable calls
        事例/患者 1: // acquire()
            pThis->acquireProxy(); // 非,不,無 事実上の call!
            eRet = typelib_TypeClass_VOID;
            break;
        事例/患者 2: // 解放(する)()
            pThis->releaseProxy(); // 非,不,無 事実上の call!
            eRet = typelib_TypeClass_VOID;
            break;
        事例/患者 0: // queryInterface() 選ぶ
        {
            typelib_TypeDescription * pTD = 0;
            TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[3] )->getTypeLibType() );
            OSL_ASSERT( pTD );
            
            XInterface * pInterface = 0;
            (*pThis->pBridge->pCppEnv->getRegisteredInterface)(
                pThis->pBridge->pCppEnv,
                (無効の **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
            
            if (pInterface)
            {
                uno_any_construct( reinterpret_cast< uno_Any * >( pCallStack[2] ),
                                   &pInterface, pTD, cpp_acquire );
                pInterface->解放(する)();
                TYPELIB_DANGER_RELEASE( pTD );
                *(無効の **)pRegisterReturn = pCallStack[2];
                eRet = typelib_TypeClass_ANY;
                break;
            }
            TYPELIB_DANGER_RELEASE( pTD );
        } // else 成し遂げる queryInterface()
        default:
            eRet = cpp2uno_call(
                pThis, aMemberDescr.get(),
                ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
                ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
                ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
                pCallStack, pRegisterReturn );
        }
        break;
    }
    default:
    {
        throw RuntimeException(
            OUString( RTL_CONSTASCII_USTRINGPARAM("no member description 設立する!") ),
            (XInterface *)pThis );
        // is here for 模造の
        eRet = typelib_TypeClass_VOID;
    }
    }

    return eRet;
}

The cpp_mediate() 機能(する)/行事 looks up the called vtable 索引, gets the せいにする or method type description, and calls cpp2uno_call(), 成し遂げるing the actual UNO 派遣(する) call.

An 利益/興味ing optimization is done on queryInterface() (vtable slot 0): Instead of 成し遂げるing the call, the source 環境 is asked for a 登録(する)d interface. If there is no 登録(する)d interface, then the call has to be 成し遂げるd.

static typelib_TypeClass cpp2uno_call(
    cppu_cppInterfaceProxy * pThis,
    const typelib_TypeDescription * pMemberTypeDescr,
    typelib_TypeDescriptionReference * pReturnTypeRef, // 0 示すs 無効の return
    sal_Int32 nParams, typelib_MethodParameter * pParams,
    無効の ** pCallStack,
    sal_Int64 * pRegisterReturn /* space for 登録(する) return */ )
{
    // pCallStack: ret, this, [コンビナート/複合体 return ptr], params
    char * pCppStack = (char *)(pCallStack +2);

    // return
    typelib_TypeDescription * pReturnTypeDescr = 0;
    if (pReturnTypeRef)
        TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
    
    無効の * pUnoReturn = 0;
    無効の * pCppReturn = 0; // コンビナート/複合体 return ptr: if != 0 && != pUnoReturn, reconversion need
    
    if (pReturnTypeDescr)
    {
        if (cppu_isSimpleType( pReturnTypeDescr ))
        {
            pUnoReturn = pRegisterReturn; // direct way for simple types
        }
        else // コンビナート/複合体 return 経由で ptr (pCppReturn)
        {
            pCppReturn = *(無効の **)pCppStack;
            pCppStack += sizeof(無効の *);
            
            pUnoReturn = (cppu_relatesToInterface( pReturnTypeDescr )
                          ? alloca( pReturnTypeDescr->nSize )
                          : pCppReturn); // direct way
        }
    }

    // stack space
    OSL_ENSHURE( sizeof(無効の *) == sizeof(sal_Int32), "### 予期しない size!" );
    // parameters
    無効の ** pUnoArgs = (無効の **)alloca( 4 * sizeof(無効の *) * nParams );
    無効の ** pCppArgs = pUnoArgs + nParams;
    // indices of values this have to be 変えるd (interface 転換 cpp<=>uno)
    sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
    // type descriptions for reconversions
    typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
    
    sal_Int32 nTempIndizes = 0;
    
    for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
    {
        const typelib_MethodParameter & rParam = pParams[nPos];
        typelib_TypeDescription * pParamTypeDescr = 0;
        TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );

        if (!rParam.bOut && cppu_isSimpleType( pParamTypeDescr )) // value
        {
            pCppArgs[nPos] = pCppStack;
            pUnoArgs[nPos] = pCppStack;
            switch (pParamTypeDescr->eTypeClass)
            {
            事例/患者 typelib_TypeClass_HYPER:
            事例/患者 typelib_TypeClass_UNSIGNED_HYPER:
            事例/患者 typelib_TypeClass_DOUBLE:
                pCppStack += sizeof(sal_Int32); // extra long
            }
            // no longer needed
            TYPELIB_DANGER_RELEASE( pParamTypeDescr );
        }
        else // ptr to コンビナート/複合体 value | ref
        {
            pCppArgs[nPos] = *(無効の **)pCppStack;

            if (! rParam.bIn) // is pure out
            {
                // uno out is unconstructed mem!
                pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
                pTempIndizes[nTempIndizes] = nPos;
                // will be 解放(する)d at reconversion
                ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
            }
            // is in/inout
            else if (cppu_relatesToInterface( pParamTypeDescr ))
            {
                uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
                                        *(無効の **)pCppStack, pParamTypeDescr,
                                        &pThis->pBridge->aCpp2Uno );
                pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
                // will be 解放(する)d at reconversion
                ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
            }
            else // direct way
            {
                pUnoArgs[nPos] = *(無効の **)pCppStack;
                // no longer needed
                TYPELIB_DANGER_RELEASE( pParamTypeDescr );
            }
        }
        pCppStack += sizeof(sal_Int32); // 基準 parameter length
    }
    
    // ExceptionHolder
    uno_Any aUnoExc; // Any will be 建設するd by callee
    uno_Any * pUnoExc = &aUnoExc;

    // invoke uno 派遣(する) call
    (*pThis->pUnoI->pDispatcher)( pThis->pUnoI, pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
    
    // in 事例/患者 an exception occurred...
    if (pUnoExc)
    {
        // destruct 一時的な in/inout params
        while (nTempIndizes--)
        {
            sal_Int32 nIndex = pTempIndizes[nTempIndizes];
            
            if (pParams[nIndex].bIn) // is in/inout => was 建設するd
                uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
            TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
        }
        if (pReturnTypeDescr)
            TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
        
        msci_raiseException( &aUnoExc, &pThis->pBridge->aUno2Cpp ); // has to destruct the any
        // is here for 模造の
        return typelib_TypeClass_VOID;
    }
    else // else no exception occurred...
    {
        // 一時的な params
        while (nTempIndizes--)
        {
            sal_Int32 nIndex = pTempIndizes[nTempIndizes];
            typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
            
            if (pParams[nIndex].bOut) // inout/out
            {
                // 変える and 割り当てる
                uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
                uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
                                        &pThis->pBridge->aUno2Cpp );
            }
            // destroy temp uno param
            uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
            
            TYPELIB_DANGER_RELEASE( pParamTypeDescr );
        }
        // return
        if (pCppReturn) // has コンビナート/複合体 return
        {
            if (pUnoReturn != pCppReturn) // needs reconversion
            {
                uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
                                        &pThis->pBridge->aUno2Cpp );
                // destroy temp uno return
                uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
            }
            // コンビナート/複合体 return ptr is 始める,決める to eax
            *(無効の **)pRegisterReturn = pCppReturn;
        }
        if (pReturnTypeDescr)
        {
            typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
            TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
            return eRet;
        }
        else
            return typelib_TypeClass_VOID;
    }
}

The cpp2uno_call() 機能(する)/行事 reads C++ parameters from the call stack and 変えるs to binary (C-) UNO, if needed (C++ and UNO values are binary 両立できる 関心ing the memory layout). If the UNO 派遣(する) call has returned and no exception has been signalled (pUnoExc), all out parameters are written 支援する to C++.

UNO Stub

If a Visual C++ interface is be mapped to binary UNO (i.e. the 中間の 環境), and that interface is mapped to another compiler 環境, then an UNO stub is created , 委任する/代表ing all UNO 派遣(する) calls to its corresponding C++ interface (in this 事例/患者 Microsoft Visual C++).

後継の calls on the UNO interface (i.e. calls of the 派遣(する) 機能(する)/行事) are 成し遂げるd by 変えるing the call parameters and 押し進めるing them on the 加工業者 stack, then calling the 需要・要求するd vtable slot on the 目的地 interface.
Any C++ exception is caught and 報告(する)/憶測d as an out parameter to the 報知係. If no exception occurred, inout/ out parameters are 変えるd and written.

The UNO stub 実施 is referred as the cppu_unoInterfaceProxy class, because it 機能(する)/行事s as an UNO proxy of a C++ interface:

struct cppu_unoInterfaceProxy : public uno_Interface
{
    oslInterlockedCount                    nRef;
    cppu_Bridge *                          pBridge;
    
    // mapping (警察などへの)密告,告訴(状)
    ::com::sun::星/主役にする::uno::XInterface *    pCppI; // wrapped interface
    typelib_InterfaceTypeDescription *     pTypeDescr;
    ::rtl::OUString                        oid;
    
    // ctor
    inline cppu_unoInterfaceProxy( cppu_Bridge * pBridge_,
                                   ::com::sun::星/主役にする::uno::XInterface * pCppI_,
                                   typelib_InterfaceTypeDescription * pTypeDescr_,
                                   const ::rtl::OUString & rOId_ );
};

The UNO stub manages its 言及/関連 count, a pointer to its 橋(渡しをする) to 接近 its 相当するもの mapping, the C++ interface it 委任する/代表s 後継の 派遣(する) calls to, the (interface) type it is emulating and an 反対する identifier (oid).

The 派遣(する) 機能(する)/行事 uno_Interface::pDispatcher() distinguishes between せいにする read/ 令状 接近 and method calls from the UNO 視野, calling the 訂正する C++ 事実上の 機能(する)/行事:

無効の SAL_CALL cppu_unoInterfaceProxy_dispatch(
    uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
    無効の * pReturn, 無効の * pArgs[], uno_Any ** ppException )
{
    // is my surrogate
    cppu_unoInterfaceProxy * pThis = static_cast< cppu_unoInterfaceProxy * >( pUnoI );
    typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
    
    switch (pMemberDescr->eTypeClass)
    {
    事例/患者 typelib_TypeClass_INTERFACE_ATTRIBUTE:
    {
        // 決定する vtable call 索引
        sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
        OSL_ENSHURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of 範囲!" );
        
        sal_Int32 nVtableCall = pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos];
        OSL_ENSHURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### 違法な vtable 索引!" );
        
        typelib_TypeDescriptionReference * pRuntimeExcRef = 0;
        
        if (pReturn)
        {
            // 扶養家族 派遣(する)
            cpp_call( pThis, nVtableCall,
                      ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
                      0, 0, // no params
                      1, &pRuntimeExcRef, // RuntimeException
                      pReturn, pArgs, ppException );
        }
        else
        {
            // is SET
            typelib_MethodParameter aParam;
            aParam.pTypeRef =
                ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
            aParam.bIn        = sal_True;
            aParam.bOut        = sal_False;
            
            typelib_TypeDescriptionReference * pReturnTypeRef = 0;
            OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("無効の") );
            typelib_typedescriptionreference_new(
                &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
            
            // 扶養家族 派遣(する)
            cpp_call( pThis, nVtableCall +1, // get, then 始める,決める method
                      pReturnTypeRef,
                      1, &aParam,
                      1, &pRuntimeExcRef,
                      pReturn, pArgs, ppException );
            
            typelib_typedescriptionreference_release( pReturnTypeRef );
        }
        
        break;
    }
    事例/患者 typelib_TypeClass_INTERFACE_METHOD:
    {
        // 決定する vtable call 索引
        sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
        OSL_ENSHURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of 範囲!" );
        
        sal_Int32 nVtableCall = pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos];
        OSL_ENSHURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### 違法な vtable 索引!" );
        
        switch (nVtableCall)
        {
            // 基準 calls
        事例/患者 1: // acquire uno interface
            (*pUnoI->acquire)( pUnoI );
            *ppException = 0;
            break;
        事例/患者 2: // 解放(する) uno interface
            (*pUnoI->解放(する))( pUnoI );
            *ppException = 0;
            break;
        事例/患者 0: // queryInterface() 選ぶ
        {
            typelib_TypeDescription * pTD = 0;
            TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
            OSL_ASSERT( pTD );
            
            uno_Interface * pInterface = 0;
            (*pThis->pBridge->pUnoEnv->getRegisteredInterface)(
                pThis->pBridge->pUnoEnv,
                (無効の **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
            
            if (pInterface)
            {
                uno_any_construct( reinterpret_cast< uno_Any * >( pReturn ), &pInterface, pTD, 0 );
                (*pInterface->解放(する))( pInterface );
                TYPELIB_DANGER_RELEASE( pTD );
                *ppException = 0;
                break;
            }
            TYPELIB_DANGER_RELEASE( pTD );
        } // else 成し遂げる queryInterface()
        default:
            // 扶養家族 派遣(する)
            cpp_call( pThis, nVtableCall,
                      ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
                      ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
                      ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
                      ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nExceptions,
                      ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->ppExceptions,
                      pReturn, pArgs, ppException );
        }
        break;
    }
    default:
    {
        ::com::sun::星/主役にする::uno::RuntimeException aExc(
            OUString( RTL_CONSTASCII_USTRINGPARAM("違法な member type description!") ),
            pThis->pCppI );
        
        typelib_TypeDescription * pTD = 0;
        const Type & rExcType = ::getCppuType( (const ::com::sun::星/主役にする::uno::RuntimeException *)0 );
        TYPELIB_DANGER_GET( &pTD, rExcType.getTypeLibType() );
        uno_any_construct( *ppException, &aExc, pTD, 0 );
        TYPELIB_DANGER_RELEASE( pTD );
    }
    }
}

その上の on cpp_call() is called given the C++ interface pointer, vtable 索引 and all parameters to 成し遂げる the C++ 事実上の 機能(する)/行事 call. The given parameters are still binary (C-) UNO values that may be 変えるd to fit the compiler 環境 (i.e. an UNO interface must be mapped to a C++ interface). The cpp_call() 機能(する)/行事 準備するs an array of longs (stack parameters) and calls callVirtualMethod(), an 議会 機能(する)/行事 成し遂げるing the Microsoft 明確な/細部 事実上の call having the 権利 登録(する)s 始める,決める:

static 無効の cpp_call(
    cppu_unoInterfaceProxy * pThis,
    sal_Int32 nVtableCall,
    typelib_TypeDescriptionReference * pReturnTypeRef,
    sal_Int32 nParams, typelib_MethodParameter * pParams,
    sal_Int32 nExceptions, typelib_TypeDescriptionReference ** ppExceptionRefs,
    無効の * pUnoReturn, 無効の * pUnoArgs[], uno_Any ** ppUnoExc )
{
    // max space for: [コンビナート/複合体 ret ptr], values|ptr ...
    char * pCppStack        = (char *)alloca( sizeof(sal_Int32) + (nParams * sizeof(sal_Int64)) );
    char * pCppStackStart    = pCppStack;
    
    // return
    typelib_TypeDescription * pReturnTypeDescr = 0;
    TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
    OSL_ENSHURE( pReturnTypeDescr, "### 推定する/予想するd return type description!" );
    
    無効の * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
    
    if (pReturnTypeDescr)
    {
        if (cppu_isSimpleType( pReturnTypeDescr ))
        {
            pCppReturn = pUnoReturn; // direct way for simple types
        }
        else
        {
            // コンビナート/複合体 return 経由で ptr
            pCppReturn = *(無効の **)pCppStack = (cppu_relatesToInterface( pReturnTypeDescr )
                                                ? alloca( pReturnTypeDescr->nSize )
                                                : pUnoReturn); // direct way
            pCppStack += sizeof(無効の *);
        }
    }

    // stack space

    OSL_ENSHURE( sizeof(無効の *) == sizeof(sal_Int32), "### 予期しない size!" );
    // args
    無効の ** pCppArgs  = (無効の **)alloca( 3 * sizeof(無効の *) * nParams );
    // indices of values this have to be 変えるd (interface 転換 cpp<=>uno)
    sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
    // type descriptions for reconversions
    typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
    
    sal_Int32 nTempIndizes   = 0;
    
    for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
    {
        const typelib_MethodParameter & rParam = pParams[nPos];
        typelib_TypeDescription * pParamTypeDescr = 0;
        TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
        
        if (!rParam.bOut && cppu_isSimpleType( pParamTypeDescr ))
        {
            uno_copyAndConvertData( pCppArgs[nPos] = pCppStack, pUnoArgs[nPos], pParamTypeDescr,
                                    &pThis->pBridge->aUno2Cpp );
            
            switch (pParamTypeDescr->eTypeClass)
            {
            事例/患者 typelib_TypeClass_HYPER:
            事例/患者 typelib_TypeClass_UNSIGNED_HYPER:
            事例/患者 typelib_TypeClass_DOUBLE:
                pCppStack += sizeof(sal_Int32); // extra long
            }
            // no longer needed
            TYPELIB_DANGER_RELEASE( pParamTypeDescr );
        }
        else // ptr to コンビナート/複合体 value | ref
        {
            if (! rParam.bIn) // is pure out
            {
                // cpp out is 建設するd mem, uno out is not!
                uno_constructData(
                    *(無効の **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
                    pParamTypeDescr );
                pTempIndizes[nTempIndizes] = nPos; // default 建設するd for cpp call
                // will be 解放(する)d at reconversion
                ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
            }
            // is in/inout
            else if (cppu_relatesToInterface( pParamTypeDescr ))
            {
                uno_copyAndConvertData(
                    *(無効の **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
                    pUnoArgs[nPos], pParamTypeDescr,
                    &pThis->pBridge->aUno2Cpp );
                
                pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
                // will be 解放(する)d at reconversion
                ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
            }
            else // direct way
            {
                *(無効の **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
                // no longer needed
                TYPELIB_DANGER_RELEASE( pParamTypeDescr );
            }
        }
        pCppStack += sizeof(sal_Int32); // 基準 parameter length
    }

    // only try-finally/ try-except 声明s possible...
    __try
    {
        __try
        {
            // pCppI is msci this pointer
            callVirtualMethod(
                pThis->pCppI, nVtableCall,
                pCppReturn, pReturnTypeDescr->eTypeClass,
                (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
            
            // NO exception occurred...
            *ppUnoExc = 0;
            
            // reconvert 一時的な params
            while (nTempIndizes--)
            {
                sal_Int32 nIndex = pTempIndizes[nTempIndizes];
                typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
                
                if (pParams[nIndex].bIn)
                {
                    if (pParams[nIndex].bOut) // inout
                    {
                        uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
                        uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
                                                &pThis->pBridge->aCpp2Uno );
                    }
                }
                else // pure out
                {
                    uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
                                            &pThis->pBridge->aCpp2Uno );
                }
                // destroy temp cpp param => cpp: every param was 建設するd
                uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
                
                TYPELIB_DANGER_RELEASE( pParamTypeDescr );
            }
            // return value
            if (pCppReturn && pUnoReturn != pCppReturn)
            {
                uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
                                        &pThis->pBridge->aCpp2Uno );
                uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
            }
        }
        __except (msci_filterCppException( GetExceptionInformation(),
                                           *ppUnoExc, &pThis->pBridge->aCpp2Uno ))
        {
            // *ppUnoExc is untouched and any was 建設するd by filter 機能(する)/行事
            // __finally 封鎖する will be called
            return;
        }
    }
    __finally
    {
        // cleanup of params was already done in reconversion 宙返り飛行 if no exception occurred;
        // this is quicker than getting all param descriptions twice!
        // so cleanup only if an exception occurred:
        if (*ppUnoExc)
        {
            // 一時的な params
            while (nTempIndizes--)
            {
                sal_Int32 nIndex = pTempIndizes[nTempIndizes];
                // destroy temp cpp param => cpp: every param was 建設するd
                uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
                TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
            }
        }
        // return type
        if (pReturnTypeDescr)
            TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
    }
}

Finally callVirtualMethod() 成し遂げるs the C++ call, copying the given stack parameters and 蓄える/店ing return values passed 支援する in 登録(する)s.

static 無効の callVirtualMethod(
   無効の * pThis, sal_Int32 nVtableIndex,
   無効の * pRegisterReturn, typelib_TypeClass eReturnTypeClass,
   sal_Int32 * pStackLongs, sal_Int32 nStackLongs )
{
    // parameter 名簿(に載せる)/表(にあげる) is mixed 名簿(に載せる)/表(にあげる) of * and values
    // 言及/関連 parameters are pointers

    OSL_ENSHURE( pStackLongs && pThis, "### null ptr!" );
    OSL_ENSHURE( (sizeof(無効の *) == 4) &&
                 (sizeof(sal_Int32) == 4), "### 予期しない size of int!" );
    
__asm
    {
        mov        eax, nStackLongs
        実験(する)       eax, eax
        je         Lcall
        // copy values
        mov        ecx, eax
        shl        eax, 2             // sizeof(sal_Int32) == 4
        追加する        eax, pStackLongs   // params stack space
Lcopy:  sub        eax, 4
        押し進める       dword ptr [eax]
        dec        ecx
        jne        Lcopy
Lcall:
        // call
        mov        ecx, pThis
        押し進める       ecx                // this ptr
        mov        edx, [ecx]         // pvft
        mov        eax, nVtableIndex
        shl        eax, 2             // sizeof(無効の *) == 4
        追加する        edx, eax
        call       [edx]              // interface method call must be __cdecl!!!

        // 登録(する) return
        mov        ecx, eReturnTypeClass
        cmp        ecx, typelib_TypeClass_VOID
        je         Lcleanup
        mov        ebx, pRegisterReturn
// int32
        cmp        ecx, typelib_TypeClass_LONG
        je         Lint32
        cmp        ecx, typelib_TypeClass_UNSIGNED_LONG
        je         Lint32
        cmp        ecx, typelib_TypeClass_ENUM
        je         Lint32
// int8
        cmp        ecx, typelib_TypeClass_BOOLEAN
        je         Lint8
        cmp        ecx, typelib_TypeClass_BYTE
        je         Lint8
// int16
        cmp        ecx, typelib_TypeClass_CHAR
        je         Lint16
        cmp        ecx, typelib_TypeClass_SHORT
        je         Lint16
        cmp        ecx, typelib_TypeClass_UNSIGNED_SHORT
        je         Lint16
// float
        cmp        ecx, typelib_TypeClass_FLOAT
        je         Lfloat
// 二塁打
        cmp        ecx, typelib_TypeClass_DOUBLE
        je         Ldouble
// int64
        cmp        ecx, typelib_TypeClass_HYPER
        je         Lint64
        cmp        ecx, typelib_TypeClass_UNSIGNED_HYPER
        je         Lint64
        jmp        Lcleanup // no simple type
Lint8:
        mov        byte ptr [ebx], al
        jmp        Lcleanup
Lint16:
        mov        word ptr [ebx], ax
        jmp        Lcleanup
Lfloat:
        fstp       dword ptr [ebx]
        jmp        Lcleanup
Ldouble:
        fstp       qword ptr [ebx]
        jmp        Lcleanup
Lint64:
        mov        dword ptr [ebx], eax
        mov        dword ptr [ebx+4], edx
        jmp        Lcleanup
Lint32:
        mov        dword ptr [ebx], eax
        jmp        Lcleanup
Lcleanup:
        // cleanup stack (obsolete though because of 機能(する)/行事)
        mov        eax, nStackLongs
        shl        eax, 2            // sizeof(sal_Int32) == 4
        追加する        eax, 4            // this ptr
        追加する        esp, eax
    }
}

Author: Daniel Bölzle ($Date: 2004/12/08 11:16:23 $)
Copyright 2001 Sun Microsystems, Inc., 901 San Antonio Road, Palo Alto, CA 94303 USA.

The ASF

Copyright & License | Privacy | 接触する Us | 寄付する | Thanks

Apache, OpenOffice, OpenOffice.org and the seagull logo are 登録(する)d trademarks of The Apache ソフトウェア 創立/基礎. The ASF logo is a trademark of The Apache ソフトウェア 創立/基礎. Other 指名するs appearing on the 場所/位置 may be trademarks of their 各々の owners.