summaryrefslogtreecommitdiff
path: root/cli_ure
diff options
context:
space:
mode:
authorPetr Mladek <pmladek@suse.cz>2011-08-02 18:37:13 +0200
committerPetr Mladek <pmladek@suse.cz>2013-04-30 12:05:25 +0200
commit10fb45c7fc8d521db6adae2b4b25eaec137c77fb (patch)
tree0eb2eb90d0716c9fc58a8f3f6954cd8ee18307aa /cli_ure
parent5f25dc8a564d01829f3cf9f58ed80cc83ea0eb45 (diff)
[mono] mono-component-support.diff: add mono support
Conflicts: cli_ure/prj/build.lst cli_ure/prj/d.lst Change-Id: I58285be7b14a4e128d49f00dccc17e0a5fc64248
Diffstat (limited to 'cli_ure')
-rw-r--r--cli_ure/Library_mono_loader.mk33
-rw-r--r--cli_ure/source/mono_bridge/bridge.cs29
-rw-r--r--cli_ure/source/mono_loader/mono_loader.cxx238
-rw-r--r--cli_ure/source/mono_loader/mono_loader.xml26
-rw-r--r--cli_ure/source/mono_loader/service.cxx72
5 files changed, 388 insertions, 10 deletions
diff --git a/cli_ure/Library_mono_loader.mk b/cli_ure/Library_mono_loader.mk
new file mode 100644
index 000000000000..719425e0d422
--- /dev/null
+++ b/cli_ure/Library_mono_loader.mk
@@ -0,0 +1,33 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_Library_Library,mono_loader))
+
+$(eval $(call gb_Library_add_cxxflags,mono_loader,\
+ $(MONO_CFLAGS) \
+))
+
+$(eval $(call gb_Library_use_udk_api,mono_loader))
+
+$(eval $(call gb_Library_add_ldflags,mono_loader,\
+ $(MONO_LIBS) \
+))
+
+$(eval $(call gb_Library_use_libraries,mono_loader,\
+ sal \
+ cppu \
+ cppuhelper \
+))
+
+$(eval $(call gb_Library_add_exception_objects,mono_loader,\
+ cli_ure/source/mono_loader/service \
+ cli_ure/source/mono_loader/mono_loader \
+))
+
+# vim: set noet sw=4 ts=4:
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/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 );
+ }
+}