/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
UnoInterfaceProxy::UnoInterfaceProxy(
Bridge * bridge,
uno_Interface * pUnoI,
typelib_InterfaceTypeDescription* pTD, const OUString& oid )
:RealProxy(MarshalByRefObject::typeid),
m_bridge(bridge),
m_oid(mapUnoString(oid.pData)),
m_sTypeName(m_system_Object_String)
{
m_bridge->acquire(); // create the list that holds all UnoInterfaceInfos
m_listIfaces = gcnew ArrayList(10);
m_numUnoIfaces = 0;
m_listAdditionalProxies = gcnew ArrayList();
m_nlistAdditionalProxies = 0; //put the information of the first UNO interface into the arraylist #if OSL_DEBUG_LEVEL >= 2
_numInterfaces = 0;
_sInterfaces = NULL; #endif
addUnoInterface(pUnoI, pTD);
UnoInterfaceProxy::!UnoInterfaceProxy() ///< UnoInterfaceProxy::Finalize()
{ #if OSL_DEBUG_LEVEL >= 2
sd::Trace::WriteLine(System::String::Format(
gcnew System::String("cli uno bridge: Destroying proxy " "for UNO object, OID: \n\t{0} \n\twith uno interfaces: "),
m_oid));
sd::Trace::WriteLine( mapUnoString(_sInterfaces));
rtl_uString_release(_sInterfaces); #endif //m_bridge is unmanaged, therefore we can access it in this finalizer
CliEnvHolder::g_cli_env->revokeInterface(m_oid);
m_bridge->release();
}
// we use the first interface in the list (m_listIfaces) to make // the queryInterface call
UnoInterfaceInfo^ info = static_cast<UnoInterfaceInfo^>(m_listIfaces[0]);
css::uno::TypeDescription membertd( reinterpret_cast<typelib_InterfaceTypeDescription*>(
info->m_typeDesc)->ppAllMembers[0]);
array<System::Object^>^ args = gcnew array<System::Object^>(1);
//Find out which UNO interface is being called
System::String^ sTypeName = static_cast<System::String^>(
props[m_typeNameString]);
sTypeName = sTypeName->Substring(0, sTypeName->IndexOf(','));
// Special Handling for System.Object methods if(sTypeName->IndexOf(m_system_Object_String) != -1)
{ return invokeObject(props, context, mcm);
}
// ToDo do without string conversion, an OUString is not needed here // get the type description of the call
OUString usMethodName(mapCliString(static_cast<System::String^>(
props[m_methodNameString])));
typelib_TypeDescriptionReference ** ppAllMembers =
info->m_typeDesc->ppAllMembers;
sal_Int32 numberMembers = info->m_typeDesc->nAllMembers; for ( sal_Int32 nPos = numberMembers; nPos--; )
{
typelib_TypeDescriptionReference * member_type = ppAllMembers[nPos];
// check usMethodName against fully qualified usTypeName // of member_type; usTypeName is of the form // <name> "::" <usMethodName> *(":@" <idx> "," <idx> ":" <name>)
OUString const & usTypeName =
OUString::unacquired( & member_type->pTypeName );
if (m_type->IsInterface == false) return;
array<sr::MethodInfo^>^ arThisMethods = m_type->GetMethods(); //get the inherited interfaces
array<System::Type^>^ arInheritedIfaces = m_type->GetInterfaces();
m_nInheritedInterfaces = arInheritedIfaces->Length; //array containing the number of methods for the interface and its //inherited interfaces
m_arInterfaceMethodCount = gcnew array<int^>(m_nInheritedInterfaces + 1); //determine the number of all interface methods, including the inherited //interfaces int numMethods = arThisMethods->Length; for (int i= 0; i < m_nInheritedInterfaces; i++)
{
numMethods += arInheritedIfaces[i]->GetMethods()->Length;
} //array containing MethodInfos of the cli object
m_arMethodInfos = gcnew array<sr::MethodInfo^>(numMethods); //array containing MethodInfos of the interface
m_arInterfaceMethodInfos = gcnew array<sr::MethodInfo^>(numMethods); //array containing the mapping of Uno interface pos to pos in //m_arMethodInfos
m_arUnoPosToCliPos = gcnew array<System::Int32>(numMethods); // initialize with -1 for (int i = 0; i < numMethods; i++)
m_arUnoPosToCliPos[i] = -1;
//fill m_arMethodInfos with the mappings // !!! InterfaceMapping.TargetMethods should be MethodInfo*[] according // to documentation // but it is Type*[] instead. Bug in the framework?
System::Type^ objType = m_cliI->GetType(); try
{ int index = 0; // now get the methods from the inherited interface //arInheritedIfaces[0] is the direct base interface //arInheritedIfaces[n] is the furthest inherited interface //Start with the base interface int nArLength = arInheritedIfaces->Length; for (;nArLength > 0; nArLength--)
{
sr::InterfaceMapping mapInherited = objType->GetInterfaceMap(
arInheritedIfaces[nArLength - 1]);
numMethods = mapInherited.TargetMethods->Length;
m_arInterfaceMethodCount[nArLength - 1] = numMethods; for (int i = 0; i < numMethods; i++, index++)
{
m_arMethodInfos[index] = safe_cast<sr::MethodInfo^>(
mapInherited.TargetMethods[i]);
m_arInterfaceMethodInfos[index] = safe_cast<sr::MethodInfo^>(
mapInherited.InterfaceMethods[i]);
}
} //At last come the methods of the furthest derived interface
sr::InterfaceMapping map = objType->GetInterfaceMap(m_type);
nArLength = map.TargetMethods->Length;
m_arInterfaceMethodCount[m_nInheritedInterfaces] = nArLength; for (int i = 0; i < nArLength; i++,index++)
{
m_arMethodInfos[index]= safe_cast<sr::MethodInfo^>(
map.TargetMethods[i]);
m_arInterfaceMethodInfos[index]= safe_cast<sr::MethodInfo^>(
map.InterfaceMethods[i]);
}
} catch (System::InvalidCastException^ )
{ throw BridgeRuntimeError("[cli_uno bridge] preparing proxy for cli interface: " + mapCliString(m_type->ToString()) + " \nfailed!");
}
}
sr::MethodInfo^ CliProxy::getMethodInfo(int nUnoFunctionPos, const OUString& usMethodName, MethodKind methodKind)
{
sr::MethodInfo^ ret = nullptr; //deduct 3 for XInterface methods
nUnoFunctionPos -= 3;
System::Threading::Monitor::Enter(m_arUnoPosToCliPos); try
{ int cliPos = m_arUnoPosToCliPos[nUnoFunctionPos]; if (cliPos != -1) return m_arMethodInfos[cliPos];
//create the method function name
System::String^ sMethodName = mapUnoString(usMethodName.pData); switch (methodKind)
{ case MK_METHOD: break; case MK_SET:
sMethodName = System::String::Concat( const_cast<System::String^>(Constants::sAttributeSet),
sMethodName); break; case MK_GET:
sMethodName = System::String::Concat( const_cast<System::String^>(Constants::sAttributeGet),
sMethodName); break; default:
OSL_ASSERT(0);
} //Find the cli interface method that corresponds to the Uno method // System::String* sMethodName= mapUnoString(usMethodName.pData); int indexCliMethod = -1; //If the cli interfaces and their methods are in the same order //as they were declared (inheritance chain and within the interface) //then nUnoFunctionPos should lead to the correct method. However, //the documentation does not say that this ordering is given. if (sMethodName->Equals(m_arInterfaceMethodInfos[nUnoFunctionPos]->Name))
indexCliMethod = nUnoFunctionPos; else
{ int cMethods = m_arInterfaceMethodInfos->Length; for (int i = 0; i < cMethods; i++)
{
System::String^ cliMethod = m_arInterfaceMethodInfos[i]->Name; if (cliMethod->Equals(sMethodName))
{
indexCliMethod = i; break;
}
}
} if (indexCliMethod == -1)
{ throw BridgeRuntimeError("[cli_uno bridge] CliProxy::getMethodInfo():cli object does not implement interface method: " + usMethodName);
}
m_arUnoPosToCliPos[nUnoFunctionPos] = indexCliMethod;
ret = m_arMethodInfos[indexCliMethod];
}
__finally
{
System::Threading::Monitor::Exit(m_arUnoPosToCliPos);
}
inlinevoid CliProxy::release() const
{ if (0 == osl_atomic_decrement( &m_ref ))
{ // revoke from uno env on last release, // The proxy can be resurrected if acquire is called before the uno // environment calls cli_proxy_free. cli_proxy_free will //delete the proxy. The environment does not acquire a registered //proxy.
(*m_bridge->m_uno_env->revokeInterface)(
m_bridge->m_uno_env, const_cast< CliProxy * >( this ) );
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.