using com::sun::star::beans::XIntrospectionAccess; using com::sun::star::uno::Any; using com::sun::star::uno::Reference; using com::sun::star::uno::Sequence; using com::sun::star::uno::RuntimeException; using com::sun::star::uno::XInterface; using com::sun::star::uno::Type; using com::sun::star::lang::XUnoTunnel; using com::sun::star::lang::IllegalArgumentException; using com::sun::star::beans::UnknownPropertyException; using com::sun::star::script::CannotConvertException; using com::sun::star::reflection::InvocationTargetException; using com::sun::star::reflection::XIdlMethod; using com::sun::star::reflection::ParamInfo;
#define TO_ASCII(x) OUStringToOString( x , RTL_TEXTENCODING_ASCII_US).getStr()
Adapter::~Adapter()
{ // Problem: We don't know, if we have the python interpreter lock // There is no runtime function to get to know this.
decreaseRefCount( mInterpreter, mWrappedObject.get() );
mWrappedObject.scratch();
}
// retrieve the adapter object again. It will be the same instance as before, // (the adapter factory keeps a weak map inside, which I couldn't have outside)
Reference< XInterface > unoAdapterObject =
runtime.getImpl()->cargo->xAdapterFactory->createAdapter( this, mTypes );
// uuuh, that's really expensive. The alternative would have been, to store // an instance of the introspection at (this), but this results in a cyclic // reference, which is never broken (as it is up to OOo1.1.0).
Reference< XIntrospectionAccess > introspection =
runtime.getImpl()->cargo->xIntrospection->inspect( Any( unoAdapterObject ) );
if( !introspection.is() )
{ throw RuntimeException(
u"pyuno bridge: Couldn't inspect uno adapter ( the python class must implement com.sun.star.lang.XTypeProvider !)"_ustr );
}
ret = comphelper::containerToSequence(retVec);
} // guard active again !
m_methodOutIndexMap[ functionName ] = ret;
} else
{
ret = ii->second;
} return ret;
}
Any Adapter::invoke( const OUString &aFunctionName, const Sequence< Any >& aParams,
Sequence< sal_Int16 > &aOutParamIndex,
Sequence< Any > &aOutParam)
{
Any ret;
// special hack for the uno object identity concept. The XUnoTunnel.getSomething() call is // always handled by the adapter directly. if( aParams.getLength() == 1 && aFunctionName == "getSomething" )
{
Sequence< sal_Int8 > id; if( aParams[0] >>= id ) return css::uno::Any( getSomething( id ) );
sal_Int32 size = aParams.getLength();
PyRef argsTuple(PyTuple_New( size ), SAL_NO_ACQUIRE, NOT_NULL ); int i; // fill tuple with default values in case of exceptions for( i = 0 ;i < size ; i ++ )
{
Py_INCREF( Py_None );
PyTuple_SetItem( argsTuple.get(), i, Py_None );
}
// convert args to python for( i = 0; i < size ; i ++ )
{
PyRef val = runtime.any2PyObject( aParams[i] );
// any2PyObject() can release the GIL if( !Py_IsInitialized() ) throw InvocationTargetException();
PyTuple_SetItem( argsTuple.get(), i, val.getAcquired() );
}
// get callable
PyRef method(PyObject_GetAttrString( mWrappedObject.get(), TO_ASCII(aFunctionName)),
SAL_NO_ACQUIRE);
if( ret.hasValue() &&
ret.getValueTypeClass() == css::uno::TypeClass_SEQUENCE &&
aFunctionName != "getTypes" && // needed by introspection itself !
aFunctionName != "getImplementationId" ) // needed by introspection itself !
{ // the sequence can either be // 1) a simple sequence return value // 2) a sequence, where the first element is the return value // and the following elements are interpreted as the outparameter // I can only decide for one solution by checking the method signature, // so I need the reflection of the adapter !
aOutParamIndex = getOutIndexes( aFunctionName ); if( aOutParamIndex.hasElements() )
{ // out parameters exist, extract the sequence
Sequence< Any > seq; if( ! ( ret >>= seq ) )
{ throw RuntimeException( "pyuno bridge: Couldn't extract out parameters for method " + aFunctionName );
}
auto nOutLength = aOutParamIndex.getLength(); if( nOutLength + 1 != seq.getLength() )
{
OUString sMsg = "pyuno bridge: expected for method "
+ aFunctionName
+ " one return value and "
+ OUString::number(nOutLength)
+ " out parameters, got a sequence of "
+ OUString::number(seq.getLength())
+ " elements as return value."; throw RuntimeException( sMsg, *this );
}
aOutParam.realloc( nOutLength );
ret = seq[0];
std::copy_n(std::next(std::cbegin(seq)), nOutLength, aOutParam.getArray());
} // else { sequence is a return value !}
}
}
Any Adapter::getValue( const OUString & aPropertyName )
{
Any ret;
PyThreadAttach guard( mInterpreter );
{ // Should probably be InvocationTargetException, but the interface doesn't allow it if( !Py_IsInitialized() ) throw RuntimeException();
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 und die Messung sind noch experimentell.