Notes on Mono integration

+ Work from cli_ure
    + de-louse prj/build.lst dependencies
        + check for MCS in config_office/configure.in, util/makefile.pmk
        + rename csc -> $(CSC) & set it up right.
            + mcs can't cope with '-o'
                  ** We should switch to -optimize instead. **
        + rene has a patch for this
          http://people.debian.org/~rene/openoffice.org/mono.diff

    + All(?) the C++ here is managed C++ (CFLAGS contains -clr)

+ cli_ure/source/basetypes/uno
    + C# implementations according to
      http://udk.openoffice.org/common/man/draft/uno_dotnet_typemapping.html
      of uno.Any
    + Contrary to that specification, there is no MethodAttribute, but
      separate custom attributes for
        + Bound (UNO) attributes, (i.e. properties)
        + Exceptions that methods may throw
        + Oneway methods
    + PolymorphicType, TypeParameters Attribute (for classes), TypeArguments
      Attribute (for fields in classes with TypeParameters) to emulate UNO
      structs with type arguments.
    + compiles with msc without problems

+ cli_ure/source/climaker
    + takes one or more uno registry files (.rdb) and emits an assembly
      containing the mapped types, mapped according to:
      http://udk.openoffice.org/common/man/draft/uno_dotnet_typemapping.html
    + output looks like
      http://udk.openoffice.org/cli/download/CLI-UNO.zip - cli_types.dll
    + uses System.Reflection.Emit to build the assembly
    + uses the native C++ UNO binding to read the registry files and for
      reflection of UNO types
    + uses native C++ to be able to use OUString
    + Tests in cli_ure/tests/climaker

+ cli_ure/source/native
    + produces cli_cppuhelper.dll as found in CLI-UNO.zip
    + "Provides bootstrapping code to bootstrap native UNO"
    + native_share.h:
        + to_cli
            + get a mapping <compiler's c++ abi>->cli (uses the uno2cli
              mapping impl. in the cli_uno bridge)
            + it uses the C++ wrapper Mapping which consists entirely of
              inline functions that use the C uno_Mapping
            + get the CLI proxy
            + extracts the object reference from the returned GCHandle
        + to_uno -- unused (!)
            + get a mapping cli-><compiler's c++ abi>
            + wrap the object reference in a new GCHandle
            + get the C++ proxy
            + wrap it in com::sun::star::uno::Reference < T >
    + native_bootstrap.cxx:
        + implementation of defaultBootstrap_InitialComponentContext as used
          in cli_language_binding.sxw from CLI-UNO.zip
        + uses cppuhelper's C++ native defaultBootstrap_InitialComponentContext
        + then uses to_cli to make a cli proxy for the component context
        + some Windows delayLoadHook thing
    + this is an easy? candidate for rewriting in C#, with P/Invokable glue
      for cppuhelper's defaultBootstrap_InitialComponentContext.
    + (Java uses jni but also cppuhelper; apparently cppuhelper has the only
      implementation of defaultBootstrap...;
      javaunohelper/source/bootstrap.cxx)

+ cli_ure/source/ure/uno/util
    + C# Implementation cli_ure.dll from CLI-UNO.zip
    + "Contains helper classes which are useful for implementing UNO interfaces.
      Types from this assembly are not necessarily used"
    + WeakAdapter, WeakComponentBase: description in cli_language_binding.sxw
    + WeakBase: base class for WeakComponentBase
    + DisposeGuard: IDisposable, "Helper class to conveniently auto dispose
      UNO objects from within managed code."
    + depends on cli_types.dll, otherwise this should be no problem for mcs

+ cli_ure/unotypes
    + use climaker to generate cli_types.dll as found in CLI-UNO.zip

+ cli_ure/util
    + Makefile snippets
    + uses -o in CSCFLAGS

+ cli_ure/workbench/dynload/dynload.cs
    + a test program for Bootstrap / cli_cppuhelper?

+ bridges/source/cli_uno/*

    + cli_bridge.h -- forked from jni_bridge.h
        + struct Mapping : public uno_Mapping { Bridge* m_bridge; };
            - uno_Mapping is a C struct
            - m_bridge: pointer to the real implementation

    + cli_bridge.cxx
        + uno_initEnvironment
            - installs cli_env_disposing callback (called before the env is destroyed)
            - nulls pExtEnv (would be "interface registration functionality, if supported")
            - could be used to start mono -- the java bridge doesn't init its jvm here.
	      Instead of setting pContext here, it's comes from the 3rd parameter of
	      uno_getEnvironment, called (using JNI) in
	      com.sun.star.comp.helper.Bootstrap.cppuhelper_bootstrap and in
	      com.sun.star.comp.helper.RegistryServiceFactory.createRegistryServiceFactory
        
        + uno_ext_getMapping
            - "is called by the UNO runtime to get the mappings for both directions"
            - ppMapping: [inout] parameter to contain the (new) mapping
            - pFrom, pTo: envs to map between
            - test their type names for being {"cli", "uno"}
            - construct a Bridge (cli-env, uno-env, <direction is cli -> uno?>)
        
        + Mapping_acquire, Mapping_release: call the corresponding Bridge methods
        
        + Bridge_free: delete the Bridge
        
        + Mapping_cli2uno
            - implementation of mapInterface for the cli2uno Mapping
            - Parameters:
                - mapping - the mapping
                - ppOut   - [inout] destination interface; existing interfaces are released
                - pIn     - source interface (in the cli environment)
                - td      - type description of the interface
            - cliObj = GCHandle::op_Explicit((intptr_t)pIn).Target: the object reference stored in pIn
            - bridge->map_cli2uno(cliObj, td) -- implementation in cli_data.cxx
        
        + Mapping_uno2cli
            - implementation of mapInterface for the uno2cli mapping
            - free ppOut if not NULL
            - bridge->map_uno2cli((uno_Interface *)pIn, td) -- in cli_data.cxx
            - wrap the resulting object reference in a GCHandle, return as a pointer
        
        + Mapping_uno2cli and Mapping_cli2uno contain managed-unmanaged transitions IIUC

    + cli_data.cxx
        + map_uno2cli: get the mapped type, try to get the Proxy from
	  the Cli_environment and add new interfaces to the Proxy if
	  necessary, if there is no existing proxy, make a new one.
	+ map_cli2uno: get the UNO proxy from the uno_Environment (C-API),
	  create a CliProxy, return that.
	+ loadCliType: load the mapped System.Type from a (climaker-produced)
	  assembly (by name)
	+ mapUnoType: take a typelib_TypeDescriptionReference and return a
	  System.Type
	+ mapCliType: the reverse

    + cli_proxy.h, cli_proxy.cxx -- can be split into C and C# files in a straightforward way
        + UnoInterfaceInfo (managed)
            + stores a uno_Interface,
              typelib_InterfaceTypeDescription of the uno_Interface,
              the mapped cli type of the uno_Interface, the bridge
            + accesses UNO only via the core C API
        + UnoInterfaceProxy : public System.Runtime.Remoting.{Proxies.RealProxy,IRemotingTypeInfo}
          (managed)
            + proxy on the managed side
            + CanCastTo uses C++ UNO: cssu::TypeDescription because that's a Smart Pointer
            + CanCastTo calls XInterface::queryInterface via helpers and binary uno
            + invokeObject: impl. helper for Invoke of System.Object methods
            + RealProxy::Invoke implementation
        + CliProxy : public uno_Interface
            + proxy on the native side
            + keeps a list of all MethodInfos of the mapped type and its superclasses
            + a mapping of method offsets in the UNO interface and in the array of
              MethodInfos

    + cli_uno.cxx
        + Bridge::call_uno -- cli-callable wrapper for uno_Interface.pDispatcher
        + Bridge::call_cli -- native-callable wrapper for System.Reflection.MethodInfo:Invoke

    + cli_base.h
        + string constants with type names (managed/CTS and unmanaged/C++)
        + struct BridgeRuntimeError (thrown when error occur)
        + an STL allocator using rtl
        + a typelib_TypeDescription wrapper

    + cli_environment
        + holds a big string indexed threadsafe hashtable of all proxies
	+ well, WeakReference holding the proxies
	+ the keys (oids) consist of the proxy's HashCode, ";cli[0]", a GUID
	  representing the Cli_environment type, optionally an UNO interface
	  name

+ Decision
    + should attempt to link to & map specifically to Mono
        + ie. a new binding bridges/source/mono_uno/*
        + since we have no 'managed C++' equivalent
        + ergo, no point in doing slow C->Mono calls that
          then call more 'standard' .Net calls to do
          conversions/boxing etc.
        + Just map as directly to Mono types / layout
          as possible.

    + Few hours later:
        martink michael_: http://udk.openoffice.org/servlets/ReadMsg?list=dev&msgNo=2942
        michael_ martink: it's a good point to try and re-write the bridge in C# :-)
        michael_ martink: a much better plan in fact,
        michael_ martink: bin my 'go-low-level-native' suggestion I guess;

+ misc. UNO places
    + cppu/inc/uno/lbnames.h: #define UNO_LB_CLI "cli"
      [LB = language binding]
    + cppu/source/uno/lbmap.cxx: implements uno_getMapping, loading/unloading of
      bridges etc.
    + cppuhelper/source/shlib.cxx in cws_srx644_cliuno01 has #ifdef CLI_PLATFORM
      a CLI component loader?
    + testtools/source/bridgetest/cli

+ Mono notes
    + mono_gchandle_new etc. is native glue for System.GCHandles 

+ JNI bridge notes
    + a JNI_type_info is a wrapper around a jclass that has a destruct method
      to do jni_env->DeleteGlobalRef on the jclass
    + a JNI_interface_type_info is a JNI_type_info + array of jmethodIDs + ...
    + bridge->m_jni_info is a JNI_info (jni_info.h) that maps TypeDescriptions
      to JNI_type_infos

+ UNO links

    + http://api.openoffice.org/docs/DevelopersGuide/ProfUNO/ProfUNO.htm
        + UNO concepts

    + http://udk.openoffice.org/common/man/bridge.html
        + Bridge
        + Proxy - client side
        + Stub - server side
        + (c) 2001, mentions msvc 4.2, egcs; but RCS id says 2004

    + http://api.openoffice.org/docs/DevelopersGuide/AdvancedUNO/AdvancedUNO.htm
        + "Advanced UNO"
        + "Implementing UNO Language Bindings"
        + Milestones for bridge writing:
            + Unidirectional mapping (call UNO from your language, remote
               controlling the office)
            + limited Bidirectional (can implement UNO interfaces, e.g.
               Listeners)
            + Bidirectional, with ComponentLoader (can implement UNO components
              that the Global Service Manager can instantiate)
              Not (yet?) possible with CLI-UNO, according to
              cli_language_binding.sxw Chapter 8.

    + http://udk.openoffice.org/cpp/man/cpp_bridges.html
        + Implementing a C++-UNO-bridge
        + Some overlap with the previous link
        + "Environment" cppu/inc/environment.h
            - one per programming language or compiler
            - e.g. gcc3, cli
            - uno environment
        + "Mapping" cppu/inc/mapping.h
            - way to publish an interface into another environment
            - a mapped interface is called a proxy
        + "Bridge"
            - infrastructure for exchanging interfaces between two envs
            - bidirectional, i.e. one mapping for each direction

    + http://udk.openoffice.org/cli/download/CLI-UNO.zip
        + contains cli_language_binding.sxw
