diff options
author | Petr Mladek <pmladek@suse.cz> | 2011-08-02 18:37:13 +0200 |
---|---|---|
committer | Andras Timar <atimar@suse.com> | 2012-10-13 12:24:51 +0200 |
commit | 263e82d49d374fd550dfbdeb30f2596569367a9a (patch) | |
tree | 1ac26c91dda34256f8150d25b48f75c60df243f6 | |
parent | [mono] mono-climaker.diff: add mono support (diff) | |
download | core-263e82d49d374fd550dfbdeb30f2596569367a9a.tar.gz core-263e82d49d374fd550dfbdeb30f2596569367a9a.zip |
[mono] mono-component-support.diff: add mono support
-rw-r--r-- | cli_ure/prj/build.lst | 1 | ||||
-rw-r--r-- | cli_ure/prj/d.lst | 1 | ||||
-rw-r--r-- | cli_ure/source/mono_bridge/bridge.cs | 29 | ||||
-rw-r--r-- | cli_ure/source/mono_loader/makefile.mk | 51 | ||||
-rw-r--r-- | cli_ure/source/mono_loader/mono_loader.cxx | 238 | ||||
-rw-r--r-- | cli_ure/source/mono_loader/mono_loader.xml | 26 | ||||
-rw-r--r-- | cli_ure/source/mono_loader/service.cxx | 72 | ||||
-rw-r--r-- | scp2/source/ooo/ure.scp | 10 |
8 files changed, 418 insertions, 10 deletions
diff --git a/cli_ure/prj/build.lst b/cli_ure/prj/build.lst index 580c1eb9ed7c..f9560449c895 100644 --- a/cli_ure/prj/build.lst +++ b/cli_ure/prj/build.lst @@ -10,5 +10,6 @@ ure cli_ure\unotypes nmake - all ure_unotypes ure_source_version ure_source_s ure cli_ure\source\ure nmake - all ure_source_ure ure_source_bootstrap.u ure_source_version ure_source_source ure_source_basetypes ure_unotypes ure_inc NULL ure cli_ure\source\uno_bridge nmake - w,vc7 ure_source_uno_bridge ure_source_basetypes ure_unotypes ure_source_ure ure_inc NULL ure cli_ure\source\mono_bridge nmake - u ure_source_mono_bridge ure_unotypes ure_source_ure ure_inc NULL +ure cli_ure\source\mono_loader nmake - u ure_source_mono_loader ure_unotypes ure_source_ure ure_inc NULL ure cli_ure\source\native nmake - w,vc7 ure_source_native ure_source_version ure_source_source ure_source_ure ure_unotypes ure_source_uno_bridge ure_inc NULL #ure cli_ure\util nmake - w,vc7 ure_util ure_source_ure ure_source_native NULL diff --git a/cli_ure/prj/d.lst b/cli_ure/prj/d.lst index 284de4c4e0f9..54b93aef0974 100644 --- a/cli_ure/prj/d.lst +++ b/cli_ure/prj/d.lst @@ -9,6 +9,7 @@ ..\%__SRC%\bin\cli_*.config %_DEST%\bin\cli_*.config ..\%__SRC%\bin\policy*.dll %_DEST%\bin\policy*.dll ..\%__SRC%\bin\cli_uno.* %_DEST%\bin\cli_uno.* +..\%__SRC%\lib\mono_loader*.so %_DEST%\lib\mono_loader*.so ..\%__SRC%\bin\cliuno.snk %_DEST%\bin\cliuno.snk diff --git a/cli_ure/source/mono_bridge/bridge.cs b/cli_ure/source/mono_bridge/bridge.cs index df2a615f3e98..6fdd78ebfd46 100644 --- a/cli_ure/source/mono_bridge/bridge.cs +++ b/cli_ure/source/mono_bridge/bridge.cs @@ -1646,9 +1646,9 @@ public unsafe class Bridge for (int i = 0; i < nParams; ++i) { - // FIXME it's a TypeDescriptionReference - TypeDescription *type = (TypeDescription *)parameters[i].pTypeRef; - + TypeDescriptionReference *typeref = (TypeDescriptionReference *)parameters[i].pTypeRef; + TypeDescription *type = null; + TypeDescriptionReference.GetDescription(&type, typeref); unoArgPtrs[i] = unoArgs + i; if ((type->eTypeClass == TypeClass.STRUCT || type->eTypeClass == TypeClass.EXCEPTION) && @@ -1663,7 +1663,7 @@ public unsafe class Bridge if (parameters[i].bIn != 0) { // FIXME error handling - MapToUno(unoArgPtrs[i], args[i], type, false /* no assign */); + MapToUno(unoArgPtrs[i], args[i], (TypeDescription*)typeref, false /* no assign */); } } @@ -1795,13 +1795,27 @@ public unsafe class Bridge MapToManaged(ref args[i], unoArgs[i], parameters[i].pTypeRef, null, false); object invocationResult = null; + Exception exc = null; try { invocationResult = method.Invoke(managedI, args); } catch (TargetInvocationException e) { - Exception exc = e.InnerException; + exc = e.InnerException; + } + catch (Exception e) + { + exc = e; + } + if ( exc != null ) + { + if ( !( exc is unoidl.com.sun.star.uno.Exception ) ) + { + // #FIXME put more info in here trace, stack etc. ( when I + // figure out how to do that in mono ) + exc = new unoidl.com.sun.star.uno.RuntimeException( exc.ToString(), null ); + } TypeDescription* td = null; // FIXME leak TypeDescriptionReference.GetDescription(&td, MapManagedType(exc.GetType())); @@ -1811,11 +1825,6 @@ public unsafe class Bridge (*unoExc)->pData = memExc; return; } - catch (Exception e) - { - // FIXME - } - // convert out, in/out params for (int i = 0; i < nParams; ++i) { diff --git a/cli_ure/source/mono_loader/makefile.mk b/cli_ure/source/mono_loader/makefile.mk new file mode 100644 index 000000000000..ece4aedf7b56 --- /dev/null +++ b/cli_ure/source/mono_loader/makefile.mk @@ -0,0 +1,51 @@ +PRJ=..$/.. + +PRJNAME=cli_ure +TARGET=mono_loader + +VISIBILITY_HIDDEN=TRUE +NO_BSYMBOLIC= TRUE +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST=$(TARGET) +COMPRDB=$(SOLARBINDIR)$/types.rdb + +.IF "$(ENABLE_MONO)" != "YES" +dummy: + @echo "Mono binding disabled - skipping ..." +.ELSE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +CFLAGS+=$(MONO_CFLAGS) +DLLPRE = + +# ------------------------------------------------------------------ + +#.INCLUDE : ..$/cppumaker.mk + +SLOFILES= \ + $(SLO)$/service.obj \ + $(SLO)$/mono_loader.obj + +SHL1TARGET= $(TARGET)$(DLLPOSTFIX).uno +SHL1IMPLIB= i$(TARGET) + +SHL1VERSIONMAP=$(SOLARENV)/src/component.map +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +DEF1NAME=$(SHL1TARGET) + +SHL1STDLIBS= \ + $(CPPUHELPERLIB) \ + $(CPPULIB) \ + $(SALLIB) + +SHL1STDLIBS+=$(MONO_LIBS) + +SHL1DEPN= +SHL1LIBS=$(SLB)$/$(TARGET).lib + +.ENDIF +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/cli_ure/source/mono_loader/mono_loader.cxx b/cli_ure/source/mono_loader/mono_loader.cxx new file mode 100644 index 000000000000..0651bf3e17bf --- /dev/null +++ b/cli_ure/source/mono_loader/mono_loader.cxx @@ -0,0 +1,238 @@ +// MARKER(update_precomp.py): autogen include statement, do not remove +#include <comphelper/processfactory.hxx> +#include <comphelper/uno3.hxx> +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/loader/XImplementationLoader.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/util/XMacroExpander.hpp> +#include <cppuhelper/implbase2.hxx> +#include "uno/mapping.hxx" +#include "osl/file.hxx" +#include "glib/gtypes.h" + +// for debug +#include <comphelper/anytostring.hxx> + +extern "C" { +#include <mono/jit/jit.h> +#include <mono/metadata/object.h> +#include <mono/metadata/environment.h> +#include <mono/metadata/assembly.h> +#include <mono/metadata/debug-helpers.h> +#include <mono/metadata/threads.h> +} + +using namespace ::com::sun::star; +#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) + +//static const char CLIURE_DLL[] = "$URE_LIB_DIR/cli_ure.dll"; +static const char CLIURE_DLL[] = "$URE_INTERNAL_LIB_DIR/cli_ure.dll"; +typedef ::cppu::WeakImplHelper2< loader::XImplementationLoader, lang::XServiceInfo > MonoLoader_BASE; + +namespace mono_loader +{ + ::rtl::OUString SAL_CALL getImplementationName(); + + uno::Reference< uno::XInterface > SAL_CALL create( uno::Reference< uno::XComponentContext > const & xContext ) SAL_THROW( () ); + + uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(); +} + +uno::Reference< loader::XImplementationLoader > +create_object (MonoDomain *domain, MonoImage *image) +{ + MonoClass *klass; + + klass = mono_class_from_name (image, "uno.util", "ManagedCodeLoader"); + if (!klass) { + OSL_TRACE ("Can't find ManagedCodeLoader in assembly %s", mono_image_get_filename (image)); + return NULL; + } + MonoObject* obj = mono_object_new (domain, klass); + /* mono_object_new () only allocates the storage: + * it doesn't run any constructor. Tell the runtime to run + * the default argumentless constructor. + */ + mono_runtime_object_init (obj); + static uno::Reference< loader::XImplementationLoader > xLoader; + // not sure if this is correct ( I'm loosely following 'to_uno' + // method in cli_ure/source/native/native_share.h ) + + loader::XImplementationLoader* pLoader = NULL; + OSL_TRACE("About to call mapInterface for XImplementionLoader returned from Mono"); + // we are storing the object so... I guess we need to tell the gc not + // to bother about this object + //mono_gchandle_new( obj, false ); // where do we release that ? do we even need to do this? + guint32 nHandle = mono_gchandle_new( obj, true ); // where do we release that ? do we even need to do this? + uno::Mapping mapping( OUSTR( UNO_LB_CLI ), OUSTR( CPPU_CURRENT_LANGUAGE_BINDING_NAME ) ); + OSL_ASSERT( mapping.is() ); + if (! mapping.is() ) + return NULL; + + mapping.mapInterface( + reinterpret_cast< void ** >( &pLoader ), + reinterpret_cast< void * >( obj ), ::getCppuType( &xLoader ) ); + mono_gchandle_free ( nHandle ); // copying what cli_ure/source/native/native_share.h does for DotNet + xLoader.set( pLoader, SAL_NO_ACQUIRE /* takeover ownership */ ); + OSL_TRACE("We appear to have got an XImplementationLoader that has a value? %s", xLoader.is() ? "yes" : "no " ); + return xLoader; +} + + +class MonoLoader : public MonoLoader_BASE +{ + class MonoCleanUp + { + public: + MonoCleanUp() { OSL_TRACE("MonoCleanUp created "); } + ~MonoCleanUp() + { + OSL_TRACE("~MonoCleanUp"); + // loader only uses the root domain + mono_jit_cleanup (mono_get_root_domain()); + } + }; + uno::Reference< uno::XComponentContext > mxContext; + uno::Reference< loader::XImplementationLoader > mxLoader; + uno::Reference< util::XMacroExpander > mxExpander; + uno::Reference< loader::XImplementationLoader > getLoader( const char* file) + { + OSL_TRACE("** enter getLoader()"); + // init only once + static MonoDomain* domain = mono_jit_init (file); + // when is a good time to trigger clean up ? + //static MonoCleanUp cleaner; + // hmm appears we need to attach this thread to the domain + mono_thread_attach( domain ); + MonoAssembly *assembly; + + assembly = mono_domain_assembly_open ( domain, file); + OSL_TRACE("** open of assembly %s = 0x%x", file, assembly); + if ( !assembly ) + throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to open assembly " ) ) + rtl::OUString::createFromAscii( file ), NULL ); + return create_object (domain, mono_assembly_get_image (assembly)); + } + + +public: + MonoLoader( const uno::Reference< uno::XComponentContext >& rxContext ) : mxContext( rxContext ) + { + if (!(mxContext->getValueByName( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/singletons/com.sun.star.util.theMacroExpander"))) >>= mxExpander) + || !mxExpander.is()) + { + throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "component context fails to supply singleton" " com.sun.star.util.theMacroExpander of type" " com.sun.star.util.XMacroExpander")), mxContext); + } + + rtl::OUString dllUrlPath = mxExpander->expandMacros( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CLIURE_DLL ) ) ); + rtl::OUString dllPath; + if ( osl::FileBase::E_None != osl::FileBase::getSystemPathFromFileURL( + dllUrlPath, dllPath )) + { + throw uno::RuntimeException( + OUSTR("cannot get system path from file url ") + + dllPath, + uno::Reference< uno::XInterface >() ); + } + + OSL_TRACE("**** location for dll is %s", rtl::OUStringToOString( dllPath, RTL_TEXTENCODING_UTF8 ).getStr() ); + OSL_TRACE("** MonoLoader::MonoLoader() "); + mxLoader = getLoader( rtl::OUStringToOString( dllPath, RTL_TEXTENCODING_UTF8 ).getStr() ); + if ( mxLoader.is() ) + { + // set the service factory + uno::Sequence< uno::Any > args(1); + args[ 0 ] <<= rxContext->getServiceManager(); + uno::Reference< lang::XInitialization > xInitialize( mxLoader, uno::UNO_QUERY_THROW ); + OSL_TRACE("MonoLoader::MonoLoader() about to call initialise"); + xInitialize->initialize( args ); + } + else + OSL_TRACE("** MonoLoader::MonoLoader(): No Mono loader found "); + + } + ~MonoLoader() + { + OSL_TRACE("** MonoLoader::~MonoLoader() "); + } + // Methods + virtual uno::Reference< uno::XInterface > SAL_CALL activate( const ::rtl::OUString& implementationName, const ::rtl::OUString& implementationLoaderUrl, const ::rtl::OUString& locationUrl, const uno::Reference< registry::XRegistryKey >& xKey ) throw (loader::CannotActivateFactoryException, uno::RuntimeException) + { + // try to instatiate a mono loader and return a reference to it + OSL_TRACE("**** in MonoLoader::activate"); + if ( mxLoader.is() ) + { + OSL_TRACE("*** MonoLoader::activate() about to call activate on 0x%x", mxLoader.get() ); + return mxLoader->activate( implementationName, implementationLoaderUrl, locationUrl, xKey ); + } + return NULL; + } + + virtual ::sal_Bool SAL_CALL writeRegistryInfo( const uno::Reference< registry::XRegistryKey >& xKey, const ::rtl::OUString& implementationLoaderUrl, const ::rtl::OUString& locationUrl ) throw (registry::CannotRegisterImplementationException, uno::RuntimeException) + { + if ( mxLoader.is() ) + return mxLoader->writeRegistryInfo( xKey, implementationLoaderUrl, locationUrl ); + return sal_False; + } + virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (uno::RuntimeException){ return mono_loader::getImplementationName(); } + virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (uno::RuntimeException) + { + sal_Bool bRes = sal_False; + uno::Sequence< ::rtl::OUString > sServices = mono_loader::getSupportedServiceNames(); + const ::rtl::OUString* pService = sServices.getConstArray(); + const ::rtl::OUString* pEnd = sServices.getConstArray() + sServices.getLength(); + for ( ; pService != pEnd ; ++pService ) + { + if ( (*pService).equals( ServiceName ) ) + { + bRes = sal_True; + break; + } + } + return bRes; + } + virtual uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (uno::RuntimeException){ return mono_loader::getSupportedServiceNames(); } + +}; + +namespace mono_loader +{ + ::rtl::OUString SAL_CALL getImplementationName() + { + static ::rtl::OUString* pImplName = 0; + if ( !pImplName ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( !pImplName ) + { + static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.loader.MonoLoader" ) ); + pImplName = &aImplName; + } + } + return *pImplName; + } + + uno::Reference< uno::XInterface > SAL_CALL create( + uno::Reference< uno::XComponentContext > const & xContext ) + SAL_THROW( () ) + { + OSL_TRACE("** In create for monoloader"); + // mimic java loader if I read it correctly it just has a single entry + // point ( Mono implementation loader should do the same? #TODO maybe ) + // #FIXME use whatever boiler plate static initialisatioon foo that is + // available ( seem to recall there is some helpers for that ) + // static uno::Reference < lang::XTypeProvider > xLoader( new MonoLoader( xContext ) ); + // hmm lets not do it for now because I'm not sure how an exiting/shutting down office/bridge co-operates + // with the mono runtime or if it does at all :/ + uno::Reference < lang::XTypeProvider > xLoader( new MonoLoader( xContext ) ); + return xLoader; + } + + uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() + { + const ::rtl::OUString strName( ::mono_loader::getImplementationName() ); + return uno::Sequence< ::rtl::OUString >( &strName, 1 ); + } +} diff --git a/cli_ure/source/mono_loader/mono_loader.xml b/cli_ure/source/mono_loader/mono_loader.xml new file mode 100644 index 000000000000..4c1802795f57 --- /dev/null +++ b/cli_ure/source/mono_loader/mono_loader.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + + <module-name>mono_loader</module-name> + + <component-description> + <author>Noel Power </author> + <name>Mono Loader</name> + <description>Loader for components located in mono assemblies</description> + <loader-name>com.sun.star.loader.SharedLibrary</loader-name> + <language>c++</language> + <status value="drafts"/> + <supported-service>org.openoffice.loader.MonoLoader</supported-service> + <type>com.sun.star.uno.XComponentContext</type> + </component-description> + + <project-build-dependency>cppuhelper</project-build-dependency> + <project-build-dependency>cppu</project-build-dependency> + <project-build-dependency>sal</project-build-dependency> + + <runtime-module-dependency>cppuhelper3$(COM)</runtime-module-dependency> + <runtime-module-dependency>cppu3</runtime-module-dependency> + <runtime-module-dependency>sal3</runtime-module-dependency> + +</module-description> diff --git a/cli_ure/source/mono_loader/service.cxx b/cli_ure/source/mono_loader/service.cxx new file mode 100644 index 000000000000..b2f5f0917661 --- /dev/null +++ b/cli_ure/source/mono_loader/service.cxx @@ -0,0 +1,72 @@ +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "cppuhelper/implementationentry.hxx" +#include "com/sun/star/lang/XMultiServiceFactory.hpp" +#include "com/sun/star/registry/XRegistryKey.hpp" + +// ============================================================================= +// component exports +// ============================================================================= +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace mono_loader +{ + // ============================================================================= + // component operations + // ============================================================================= + + uno::Reference< XInterface > SAL_CALL create( + Reference< XComponentContext > const & xContext ) + SAL_THROW( () ); + + // ----------------------------------------------------------------------------- + + ::rtl::OUString SAL_CALL getImplementationName(); + + Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(); + + Reference<XInterface> SAL_CALL create( + Sequence<Any> const &, Reference<XComponentContext> const & ); +} // end mono_loader + + // ============================================================================= + + const ::cppu::ImplementationEntry s_component_entries [] = + { + { + ::mono_loader::create, ::mono_loader::getImplementationName, + ::mono_loader::getSupportedServiceNames, + ::cppu::createSingleComponentFactory, + 0, 0 + }, + { 0, 0, 0, 0, 0, 0 } + }; + +extern "C" +{ + SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ) + { + OSL_TRACE("In component_getImplementationEnv"); + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; + } + + SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo( + lang::XMultiServiceFactory * pServiceManager, registry::XRegistryKey * pRegistryKey ) + { + OSL_TRACE("In component_writeInfo"); + if ( ::cppu::component_writeInfoHelper( + pServiceManager, pRegistryKey, s_component_entries ) ) + return sal_True; + return sal_False; + } + + SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory( + const sal_Char * pImplName, lang::XMultiServiceFactory * pServiceManager, + registry::XRegistryKey * pRegistryKey ) + { + OSL_TRACE("In component_getFactory"); + return ::cppu::component_getFactoryHelper( + pImplName, pServiceManager, pRegistryKey, s_component_entries ); + } +} diff --git a/scp2/source/ooo/ure.scp b/scp2/source/ooo/ure.scp index 63e09ec416f6..b74d6570848f 100644 --- a/scp2/source/ooo/ure.scp +++ b/scp2/source/ooo/ure.scp @@ -439,6 +439,16 @@ File gid_File_Dl_LogUnoUno Styles = (PACKED, VERSION_INDEPENDENT_COMP_ID); End +#if ( defined UNX && defined ENABLE_MONO ) // currently we only will build this on unix +File gid_File_Dl_MonoLoader + TXT_FILE_BODY; + Dir = SCP2_URE_DL_DIR; + Name = STRING(CONCAT4(mono_loader,DLLPOSTFIX,.uno,UNXSUFFIX)); + Styles = (PACKED, UNO_COMPONENT, VERSION_INDEPENDENT_COMP_ID); + RegistryID = gid_Starregistry_Services_Rdb_Ure; +End +#endif + #if defined _MSC_VER || defined ENABLE_MONO File gid_File_Dl_Cli_Uno LIB_FILE_BODY; |