LibreOffice Module bridges (master) 1
cppinterfaceproxy.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <cppinterfaceproxy.hxx>
21
22#include <bridge.hxx>
23#include <utility>
24#include <vtablefactory.hxx>
25
26#include <com/sun/star/uno/XInterface.hpp>
27#include <typelib/typedescription.h>
28
29#include <cstddef>
30#include <memory>
31#include <new>
32
34
35void freeCppInterfaceProxy(uno_ExtEnvironment * pEnv, void * pInterface)
36{
38 pInterface);
39 if (pEnv != pThis->pBridge->getCppEnv()) {
40 assert(false);
41 }
42
43 (*pThis->pBridge->getUnoEnv()->revokeInterface)(
44 pThis->pBridge->getUnoEnv(), pThis->pUnoI );
45 (*pThis->pUnoI->release)( pThis->pUnoI );
46 ::typelib_typedescription_release(
47 &pThis->pTypeDescr->aBase );
48 pThis->pBridge->release();
49
50#if OSL_DEBUG_LEVEL > 1
51 *(int *)pInterface = 0xdeadbabe;
52#endif
53 pThis->~CppInterfaceProxy();
54 delete[] reinterpret_cast< char * >(pThis);
55}
56
57com::sun::star::uno::XInterface * CppInterfaceProxy::create(
58 bridges::cpp_uno::shared::Bridge * pBridge, uno_Interface * pUnoI,
59 typelib_InterfaceTypeDescription * pTypeDescr, OUString const & rOId)
60{
62 reinterpret_cast< typelib_TypeDescription ** >(&pTypeDescr));
65 factory.getVtables(pTypeDescr));
66 std::unique_ptr< char[] > pMemory(
67 new char[
68 sizeof (CppInterfaceProxy)
69 + (rVtables.count - 1) * sizeof (void **)]);
70 new(pMemory.get()) CppInterfaceProxy(pBridge, pUnoI, pTypeDescr, rOId);
71 CppInterfaceProxy * pProxy = reinterpret_cast< CppInterfaceProxy * >(
72 pMemory.release());
73 for (sal_Int32 i = 0; i < rVtables.count; ++i) {
75 rVtables.blocks[i].start);
76 }
77 // coverity[leaked_storage : FALSE] - see freeCppInterfaceProxy
78 return castProxyToInterface(pProxy);
79}
80
82{
83 if (++nRef == 1)
84 {
85 // rebirth of proxy zombie
86 // register at cpp env
87 void * pThis = castProxyToInterface( this );
88 (*pBridge->getCppEnv()->registerProxyInterface)(
89 pBridge->getCppEnv(), &pThis, freeCppInterfaceProxy, oid.pData,
90 pTypeDescr );
91 assert(pThis == castProxyToInterface(this));
92 }
93}
94
96{
97 if (! --nRef ) // last release
98 {
99 // revoke from cpp env
100 (*pBridge->getCppEnv()->revokeInterface)(
102 }
103}
104
106 bridges::cpp_uno::shared::Bridge * pBridge_, uno_Interface * pUnoI_,
107 typelib_InterfaceTypeDescription * pTypeDescr_, OUString aOId_)
108 : nRef( 1 )
109 , pBridge( pBridge_ )
110 , pUnoI( pUnoI_ )
111 , pTypeDescr( pTypeDescr_ )
112 , oid(std::move( aOId_ ))
113{
114 pBridge->acquire();
115 ::typelib_typedescription_acquire( &pTypeDescr->aBase );
116 (*pUnoI->acquire)( pUnoI );
117 (*pBridge->getUnoEnv()->registerInterface)(
118 pBridge->getUnoEnv(), reinterpret_cast< void ** >( &pUnoI ), oid.pData,
119 pTypeDescr );
120}
121
123{}
124
125com::sun::star::uno::XInterface * CppInterfaceProxy::castProxyToInterface(
126 CppInterfaceProxy * pProxy)
127{
128 return reinterpret_cast< com::sun::star::uno::XInterface * >(
129 &pProxy->vtables);
130}
131
133{
134 // pInterface == &pProxy->vtables (this emulated offsetof is not truly
135 // portable):
136 char const * const base = reinterpret_cast< char const * >(16);
137 std::ptrdiff_t const offset = reinterpret_cast< char const * >(
138 &reinterpret_cast< CppInterfaceProxy const * >(base)->vtables) - base;
139 return reinterpret_cast< CppInterfaceProxy * >(
140 static_cast< char * >(pInterface) - offset);
141}
142
143}
144
145/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Holding environments and mappings.
Definition: bridge.hxx:54
uno_ExtEnvironment * getCppEnv()
Definition: bridge.hxx:69
uno_ExtEnvironment * getUnoEnv()
Definition: bridge.hxx:70
A cpp proxy wrapping a uno interface.
typelib_InterfaceTypeDescription * pTypeDescr
CppInterfaceProxy(CppInterfaceProxy const &)=delete
static CppInterfaceProxy * castInterfaceToProxy(void *pInterface)
friend void freeCppInterfaceProxy(uno_ExtEnvironment *pEnv, void *pInterface)
static com::sun::star::uno::XInterface * create(Bridge *pBridge, uno_Interface *pUnoI, typelib_InterfaceTypeDescription *pTypeDescr, OUString const &rOId)
static com::sun::star::uno::XInterface * castProxyToInterface(CppInterfaceProxy *pProxy)
Hand out vtable structures for interface type descriptions.
const Vtables & getVtables(typelib_InterfaceTypeDescription *type)
Given an interface type description, return its corresponding vtable structure.
static Slot * mapBlockToVtable(void *block)
Given a pointer to a block, turn it into a vtable pointer.
void const * base
sal_Int32 nRef
struct _typelib_TypeDescription typelib_TypeDescription
Definition: msvc/except.hxx:53
void freeCppInterfaceProxy(uno_ExtEnvironment *pEnv, void *pInterface)
int i
The vtable structure corresponding to an interface type.
std::unique_ptr< Block[]> blocks
An array of blocks, representing the multiple vtables of a (multiple-inheritance) type.
sal_Int32 count
The number of blocks/vtables.
sal_Bool SAL_CALL typelib_typedescription_complete(typelib_TypeDescription **ppTypeDescr) SAL_THROW_EXTERN_C()