1 /*************************************************************************
7 * last change: $Author: $ $Date: $
9 * The Contents of this file are made available subject to the terms of
10 * either of the following licenses
12 * - GNU Lesser General Public License Version 2.1
13 * - Sun Industry Standards Source License Version 1.1
15 * Sun Microsystems Inc., October, 2000
17 * GNU Lesser General Public License Version 2.1
18 * =============================================
19 * Copyright 2000 by Sun Microsystems, Inc.
20 * 901 San Antonio Road, Palo Alto, CA 94303, USA
22 * This library is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU Lesser General Public
24 * License version 2.1, as published by the Free Software Foundation.
26 * This library is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29 * Lesser General Public License for more details.
31 * You should have received a copy of the GNU Lesser General Public
32 * License along with this library; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
37 * Sun Industry Standards Source License Version 1.1
38 * =================================================
39 * The contents of this file are subject to the Sun Industry Standards
40 * Source License Version 1.1 (the "License"); You may not use this file
41 * except in compliance with the License. You may obtain a copy of the
42 * License at http://www.openoffice.org/license.html.
44 * Software provided under this License is provided on an "AS IS" basis,
45 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
46 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
47 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
48 * See the License for the specific provisions governing your rights and
49 * obligations concerning the Software.
51 * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
53 * Copyright: 2000 by Sun Microsystems, Inc.
55 * All Rights Reserved.
57 * Contributor(s): _______________________________________
60 ************************************************************************/
62 namespace com
.sun
.star
.bridges
.mono_uno
/* FIXME use some uno.foo namespace ? */
66 using System
.Reflection
;
67 using System
.Runtime
.InteropServices
;
68 using System
.Runtime
.Remoting
;
74 public unsafe class Bridge
76 static IntPtr unoEnvironment
;
77 static cli_uno
.Cli_environment managedEnvironment
;
81 unoEnvironment
= unoEnv
;
82 managedEnvironment
= new cli_uno
.Cli_environment();
85 public unsafe IntPtr
MapManagedToUno(object managedData
, TypeDescription
*td
)
87 IntPtr result
= new IntPtr(null);
89 // get oid from managed environment
90 string oid
= cli_uno
.Cli_environment
.getObjectIdentifier(managedData
);
92 UString
* unoOid
= null;
93 UString
.NewFromString(&unoOid
, oid
);
94 uno
.Binary
.Environment
.GetRegisteredInterface(unoEnvironment
,
97 (InterfaceTypeDescription
*)td
);
98 if (result
== IntPtr
.Zero
)
99 lock (typeof(cli_uno
.Cli_environment
))
101 uno
.Binary
.Environment
.GetRegisteredInterface(unoEnvironment
,
104 (InterfaceTypeDescription
*)td
);
105 if (result
== IntPtr
.Zero
)
106 result
= CreateManagedProxy(managedData
, td
, unoOid
);
109 UString
.Release(unoOid
);
114 public unsafe object MapUnoToManaged(IntPtr unoInterface
, InterfaceTypeDescription
*iTD
)
116 object result
= null;
118 UString
* oidPtr
= null;
119 uno
.Binary
.Environment
.GetObjectIdentifier(unoEnvironment
, &oidPtr
, unoInterface
);
121 // See if the interface was already mapped
122 Type ifaceType
= MapUnoType((TypeDescription
*)iTD
);
123 string oid
= UString
.UStringToString(oidPtr
);
124 // the string is owned by unoEnvironment
127 lock (managedEnvironment
)
129 result
= managedEnvironment
.getRegisteredInterface(oid
, ifaceType
);
132 // There is already an registered object. It can either be a proxy
133 // for the UNO object or a real cli object. In the first case we
134 // tell the proxy that it shall also represent the current UNO
135 // interface. If it already does that, then it does nothing
136 if (RemotingServices
.IsTransparentProxy(result
))
138 UnoInterfaceProxy p
= (UnoInterfaceProxy
)RemotingServices
.GetRealProxy(result
);
139 p
.AddUnoInterface(unoInterface
, iTD
);
144 result
= UnoInterfaceProxy
.Create(this, unoInterface
, iTD
, oid
);
151 // FIXME convert cli types to expected types, e.g a long to a short where the uno type
152 // is a sal_Int16. This could be necessary if a scripting language (typeless) is used
153 // @param assign the uno_data has to be destructed (in/out args)
154 unsafe void MapToUno(void *unoData
, object managedData
,
155 // FIXME it's a TypeDescriptionReference
156 TypeDescription
*type
, bool assign
)
158 // FIXME acquire the TypeDescription?
159 // FIXME assert that all the type equivalences in the comments hold
160 switch (type
->eTypeClass
)
165 *(ushort *)unoData
= (char)managedData
; // sal_Unicode = ushort
167 case TypeClass
.BOOLEAN
:
168 *(byte *)unoData
= (bool)managedData
? (byte)1 : (byte)0; // sal_Bool = byte
171 *(byte *)unoData
= (byte)managedData
; // sal_Int8 = byte
173 case TypeClass
.SHORT
:
174 *(short *)unoData
= (short)managedData
; // sal_Int16 = short
176 case TypeClass
.UNSIGNED_SHORT
:
177 *(ushort *)unoData
= (ushort)managedData
; // sal_uInt16 = ushort
180 *(int *)unoData
= (int)managedData
; // sal_Int32 = int
182 case TypeClass
.UNSIGNED_LONG
:
183 *(uint *)unoData
= (uint)managedData
; // sal_uInt32 = uint
185 case TypeClass
.HYPER
:
186 *(long *)unoData
= (long)managedData
; // sal_Int64 = long
188 case TypeClass
.UNSIGNED_HYPER
:
189 *(ulong *)unoData
= (ulong)managedData
; // sal_uInt64 = ulong
191 case TypeClass
.FLOAT
:
192 *(float *)unoData
= (float)managedData
; // C++ float = C# float
194 case TypeClass
.DOUBLE
:
195 *(double *)unoData
= (double)managedData
; // C++ double = C# double
197 case TypeClass
.STRING
:
199 if (assign
&& *(UString
**)unoData
!= null)
200 UString
.Release(*(UString
**)unoData
);
202 *(UString
**)unoData
= null;
203 if (managedData
== null)
205 UString
.New((UString
**)unoData
);
209 string s
= (string)managedData
;
210 UString
.NewFromString((UString
**)unoData
, s
);
216 TypeDescriptionReference
.Release(*(TypeDescriptionReference
**)unoData
);
218 *(TypeDescriptionReference
**)unoData
= MapManagedType((Type
)managedData
);
222 uno
.Binary
.Any
*binAny
= (uno
.Binary
.Any
*)unoData
;
225 uno
.Binary
.Any
.Destroy(binAny
, null);
227 if (managedData
== null)
229 uno
.Binary
.Any
.Construct(binAny
, null, null, null);
233 uno
.Any any
= (uno
.Any
)managedData
;
234 TypeDescription
*valueTD
= (TypeDescription
*)MapManagedType(any
.Type
);
236 // if there's enough room in void *pReserved, store the value in the pointer
237 binAny
->pData
= &binAny
->pReserved
; // this triggers a bug in mcs < 1.1.4
238 switch (valueTD
->eTypeClass
)
243 *(ushort *)binAny
->pData
= (char)any
.Value
;
245 case TypeClass
.BOOLEAN
:
246 *(byte *)binAny
->pData
= (bool)any
.Value
? (byte)1 : (byte)0;
249 *(byte *)binAny
->pData
= (byte)any
.Value
;
251 case TypeClass
.SHORT
:
252 *(short *)binAny
->pData
= (short)any
.Value
;
254 case TypeClass
.UNSIGNED_SHORT
:
255 *(ushort *)binAny
->pData
= (ushort)any
.Value
;
258 *(int *)binAny
->pData
= (int)any
.Value
;
260 case TypeClass
.UNSIGNED_LONG
:
261 *(uint *)binAny
->pData
= (uint)any
.Value
;
263 case TypeClass
.HYPER
:
264 if (sizeof(long) > sizeof(void *))
265 binAny
->pData
= uno
.rtl
.Mem
.Allocate(sizeof(long));
267 *(long *)binAny
->pData
= (long)any
.Value
;
269 case TypeClass
.UNSIGNED_HYPER
:
270 if (sizeof(ulong) > sizeof(void *))
271 binAny
->pData
= uno
.rtl
.Mem
.Allocate(sizeof(ulong));
273 *(ulong *)binAny
->pData
= (ulong)any
.Value
;
275 case TypeClass
.FLOAT
:
276 if (sizeof(float) > sizeof(void *)) // FIXME can this happen?
277 binAny
->pData
= uno
.rtl
.Mem
.Allocate(sizeof(float));
279 *(float *)binAny
->pData
= (float)any
.Value
;
281 case TypeClass
.DOUBLE
:
282 if (sizeof(double) > sizeof(void *))
283 binAny
->pData
= uno
.rtl
.Mem
.Allocate(sizeof(double));
285 *(double *)binAny
->pData
= (double)any
.Value
;
287 case TypeClass
.STRING
:
288 // string anies are used so often, that we handle them
289 // separately, to be a little faster than with an
290 // extra MapToUno call
292 // the Any was already destroyed, can't contain a
293 // valid string that we could leak here.
294 *(UString
**)binAny
->pData
= null;
296 if (managedData
== null)
298 UString
.New((UString
**)binAny
->pData
);
302 string s
= (string)any
.Value
;
303 UString
.NewFromString((UString
**)binAny
->pData
, s
);
305 // the string is owned by the Any
308 *(int *) binAny
->pData
= System
.Convert
.ToInt32(any
.Value
);
311 case TypeClass
.SEQUENCE
:
312 case TypeClass
.INTERFACE
:
313 binAny
->pReserved
= null;
314 MapToUno(binAny
->pData
, any
.Value
, valueTD
, false /* no assign */);
316 case TypeClass
.STRUCT
:
317 case TypeClass
.EXCEPTION
:
318 binAny
->pData
= uno
.rtl
.Mem
.Allocate(valueTD
->nSize
);
319 MapToUno(binAny
->pData
, any
.Value
, valueTD
, false /* no assign */);
323 throw new Exception();
325 binAny
->pType
= (TypeDescriptionReference
*)valueTD
;
326 TypeDescriptionReference
.Acquire(binAny
->pType
);
330 *(int *)unoData
= System
.Convert
.ToInt32(managedData
);
332 case TypeClass
.STRUCT
:
333 case TypeClass
.EXCEPTION
:
335 TypeDescription
*td
= null; // FIXME leak
336 TypeDescriptionReference
.GetDescription(&td
, (TypeDescriptionReference
*)type
);
337 CompoundTypeDescription
*compTD
= (CompoundTypeDescription
*)td
;
338 StructTypeDescription
*structTD
= null;
340 if (type
->eTypeClass
== TypeClass
.STRUCT
)
341 structTD
= (StructTypeDescription
*)type
;
343 if (((TypeDescription
*)compTD
)->bComplete
== 0)
344 TypeDescription
.Complete((TypeDescription
**)&compTD
);
346 int members
= compTD
->nMembers
;
347 Type managedType
= null;
348 if (managedData
!= null)
349 managedType
= managedData
.GetType();
351 if (compTD
->pBaseTypeDescription
!= null)
352 MapToUno(unoData
, managedData
,
353 (TypeDescription
*)((TypeDescription
*)compTD
->pBaseTypeDescription
)->pWeakRef
,
356 TypeDescriptionReference
*memberType
= null;
357 for (int i
= 0; i
< members
; ++i
)
359 memberType
= compTD
->ppTypeRefs
[i
];
362 if (managedData
!= null)
364 string fieldName
= UString
.UStringToString(compTD
->ppMemberNames
[i
]);
365 FieldInfo fieldInfo
= managedType
.GetField(fieldName
);
366 // special case for Exception.Message property
367 // The com.sun.star.uno.Exception.Message field is mapped to the
368 // System.Exception property. Type.GetField("Message") returns null
369 if (fieldInfo
== null &&
370 UString
.UStringToString(type
->pTypeName
) == "com.sun.star.uno.Exception")
372 // get ExceptionMessage property
373 if (fieldName
== "Message")
375 PropertyInfo propInfo
= managedType
.GetProperty(fieldName
);
376 val
= propInfo
.GetValue(managedData
, null);
377 } // FIXME else throw exception
379 else if (fieldInfo
!= null)
381 val
= fieldInfo
.GetValue(managedData
);
382 } // FIXME else throw exception
385 void *p
= (byte *)unoData
+ compTD
->pMemberOffsets
[i
];
386 // When using polymorphic structs then the parameterized members can be null.
387 // Then we set a default value.
388 bool useDefault
= ((structTD
!= null &&
389 structTD
->pParameterizedTypes
!= null &&
390 structTD
->pParameterizedTypes
[i
] == 1 &&
392 managedData
== null);
393 switch (memberType
->eTypeClass
)
399 *(ushort *)p
= (char)val
;
401 case TypeClass
.BOOLEAN
:
403 *(byte *)p
= (byte)0;
405 *(byte *)p
= (bool)val
? (byte)1 : (byte)0;
409 *(byte *)p
= (byte)0;
411 *(byte *)p
= (byte)val
;
413 case TypeClass
.SHORT
:
415 *(short *)p
= (short)0;
417 *(short *)p
= (short)val
;
419 case TypeClass
.UNSIGNED_SHORT
:
421 *(ushort *)p
= (ushort)0;
423 *(ushort *)p
= (ushort)val
;
429 *(int *)p
= (int)val
;
431 case TypeClass
.UNSIGNED_LONG
:
433 *(uint *)p
= (uint)0;
435 *(uint *)p
= (uint)val
;
437 case TypeClass
.HYPER
:
439 *(long *)p
= (long)0;
441 *(long *)p
= (long)val
;
443 case TypeClass
.UNSIGNED_HYPER
:
445 *(ulong *)p
= (ulong)0;
447 *(ulong *)p
= (ulong)val
;
449 case TypeClass
.FLOAT
:
453 *(float *)p
= (float)val
;
455 case TypeClass
.DOUBLE
:
459 *(double *)p
= (double)val
;
462 // FIXME enum should be converted here
463 MapToUno(p
, val
, (TypeDescription
*)memberType
, assign
);
467 // FIXME exception handling
470 case TypeClass
.SEQUENCE
:
472 TypeDescription
*td
= null; // FIXME
473 TypeDescriptionReference
.GetDescription(&td
, (TypeDescriptionReference
*)type
);
474 TypeDescriptionReference
*elementType
=
475 ((IndirectTypeDescription
*)td
)->pType
;
477 SequencePtr seq
= new SequencePtr();
479 if (managedData
!= null)
481 Array array
= (Array
)managedData
;
482 int length
= array
.GetLength(0);
484 switch (elementType
->eTypeClass
)
487 seq
= SequencePtr
.Allocate(length
, sizeof(ushort));
488 Marshal
.Copy((char [])managedData
, 0, seq
.elementsPtr
, length
);
490 /* case TypeClass.BOOLEAN:
491 // FIXME bool vs. byte ???
492 seq = SequencePtr.Allocate(length, sizeof(byte));
493 Marshal.Copy((byte [])managedData, 0, seq.elementsPtr, length);
496 seq
= SequencePtr
.Allocate(length
, sizeof(byte));
497 Marshal
.Copy((byte [])managedData
, 0, seq
.elementsPtr
, length
);
499 case TypeClass
.SHORT
:
500 seq
= SequencePtr
.Allocate(length
, sizeof(short));
501 Marshal
.Copy((short [])managedData
, 0, seq
.elementsPtr
, length
);
503 /* case TypeClass.UNSIGNED_SHORT:
504 seq = SequencePtr.Allocate(length, sizeof(ushort));
505 Marshal.Copy((short [])managedData, 0, seq.elementsPtr, length);
508 seq
= SequencePtr
.Allocate(length
, sizeof(int));
509 Marshal
.Copy((int [])managedData
, 0, seq
.elementsPtr
, length
);
511 /* case TypeClass.UNSIGNED_LONG:
512 seq = SequencePtr.Allocate(length, sizeof(uint));
513 Marshal.Copy((int [])managedData, 0, seq.elementsPtr, length);
515 case TypeClass
.HYPER
:
516 seq
= SequencePtr
.Allocate(length
, sizeof(long));
517 Marshal
.Copy((long [])managedData
, 0, seq
.elementsPtr
, length
);
519 /* case TypeClass.UNSIGNED_HYPER:
520 seq = SequencePtr.Allocate(length, sizeof(ulong));
521 Marshal.Copy((long [])managedData, 0, seq.elementsPtr, length);
523 case TypeClass
.FLOAT
:
524 seq
= SequencePtr
.Allocate(length
, sizeof(float));
525 Marshal
.Copy((float [])managedData
, 0, seq
.elementsPtr
, length
);
527 case TypeClass
.DOUBLE
:
528 seq
= SequencePtr
.Allocate(length
, sizeof(double));
529 Marshal
.Copy((double [])managedData
, 0, seq
.elementsPtr
, length
);
531 case TypeClass
.STRING
:
533 seq
= SequencePtr
.Allocate(length
, sizeof(void *));
534 string[] stringArray
= (string [])managedData
;
535 for (int i
= 0; i
< length
; ++i
)
537 UString
** pStr
= ((UString
** )seq
.elementsPtr
) + i
;
539 UString
.NewFromString(pStr
, stringArray
[i
]);
540 // string ownership goes to callee
545 seq
= SequencePtr
.Allocate(length
, sizeof(int));
546 for (int i
= 0; i
< length
; ++i
)
547 ((int *)seq
.elementsPtr
)[i
] =
548 Convert
.ToInt32(array
.GetValue(i
));
552 case TypeClass
.STRUCT
:
553 case TypeClass
.EXCEPTION
:
554 case TypeClass
.SEQUENCE
:
555 case TypeClass
.INTERFACE
:
556 // FIXME: surely we can do better for this lot [!] - sign problems ...
557 case TypeClass
.BOOLEAN
:
558 case TypeClass
.UNSIGNED_SHORT
:
559 case TypeClass
.UNSIGNED_LONG
:
560 case TypeClass
.UNSIGNED_HYPER
:
562 seq
= SequencePtr
.Allocate(
563 length
, ((TypeDescription
*)elementType
)->nSize
);
565 for (int i
= 0; i
< length
; ++i
)
568 (byte *)seq
.elementsPtr
+
569 i
* ((TypeDescription
*)elementType
)->nSize
;
570 object elementData
= ((Array
)managedData
).GetValue(i
);
571 MapToUno(p
, elementData
,
572 (TypeDescription
*)((TypeDescription
*)elementType
)->pWeakRef
,
573 false /* no assign */);
575 // FIXME exception handling
579 break; // FIXME throw some exception
584 seq
= SequencePtr
.Allocate(0, sizeof(int));
586 *(SequencePtr
*)unoData
= seq
;
589 case TypeClass
.INTERFACE
:
591 if (assign
&& *(void **)unoData
!= null)
592 uno
.Binary
.Interface
.Release(new IntPtr(*(void **)unoData
));
594 if (managedData
== null)
595 *(void **)unoData
= null;
598 TypeDescription
*td
= null; // FIXME leak
599 TypeDescriptionReference
.GetDescription(&td
, (TypeDescriptionReference
*)type
);
600 *(void **)unoData
= MapManagedToUno(managedData
, td
).ToPointer();
605 // FIXME throw some exception
610 unsafe void MapToManaged(ref object managedData
, void *unoData
,
611 TypeDescriptionReference
*type
, Type info
, bool dontCreateObj
)
613 switch (type
->eTypeClass
)
616 managedData
= (char)*(ushort *)unoData
;
618 case TypeClass
.BOOLEAN
:
619 managedData
= (*(byte *)unoData
!= 0);
622 managedData
= *(byte *)unoData
;
624 case TypeClass
.SHORT
:
625 managedData
= *(short *)unoData
;
627 case TypeClass
.UNSIGNED_SHORT
:
628 managedData
= *(ushort *)unoData
;
631 managedData
= *(int *)unoData
;
633 case TypeClass
.UNSIGNED_LONG
:
634 managedData
= *(uint *)unoData
;
636 case TypeClass
.HYPER
:
637 managedData
= *(long *)unoData
;
639 case TypeClass
.UNSIGNED_HYPER
:
640 managedData
= *(ulong *)unoData
;
642 case TypeClass
.FLOAT
:
643 managedData
= *(float *)unoData
;
645 case TypeClass
.DOUBLE
:
646 managedData
= *(double *)unoData
;
648 case TypeClass
.STRING
:
649 managedData
= UString
.UStringToString(*(UString
**)unoData
);
652 managedData
= MapUnoType(*(TypeDescriptionReference
**)unoData
);
656 uno
.Binary
.Any
*binAny
= (uno
.Binary
.Any
*)unoData
;
657 if (binAny
->pType
->eTypeClass
!= TypeClass
.VOID
)
660 MapToManaged(ref value, binAny
->pData
, binAny
->pType
, null, false);
661 managedData
= new uno
.Any(MapUnoType(binAny
->pType
), value);
665 managedData
= uno
.Any
.VOID
;
671 managedData
= Enum
.ToObject(
672 info
.GetElementType(), *(int *)unoData
);
674 managedData
= Enum
.ToObject(
675 MapUnoType(type
), *(int *)unoData
);
677 case TypeClass
.STRUCT
:
678 case TypeClass
.EXCEPTION
:
680 TypeDescription
*td
= null; // FIXME leak
681 TypeDescriptionReference
.GetDescription(&td
, (TypeDescriptionReference
*)type
);
682 CompoundTypeDescription
*compTD
= (CompoundTypeDescription
*)td
;
684 if (((TypeDescription
*)compTD
)->bComplete
== 0)
685 TypeDescription
.Complete((TypeDescription
**)&compTD
);
688 Type managedType
= LoadCliType(td
->pTypeName
);
690 // detect if we recursivly convert inherited
691 // structures. If this point is reached because of a
692 // recursive call during converting a struct then we must
693 // not create a new object rather we use the one in
694 // cli_data argument.
695 object managedObject
;
697 managedObject
= managedData
;
700 // Special handling for Exception conversion. We must
701 // call constructor System::Exception to pass the
703 if (typeof(unoidl
.com
.sun
.star
.uno
.Exception
).IsAssignableFrom(managedType
))
705 // We need to get the Message field. Therefore we
706 // must obtain the offset from the
707 // typedescription. The base interface of all
708 // exceptions is com::sun::star::uno::Exception
709 // which contains the message
710 CompoundTypeDescription
*pCTD
= compTD
;
711 while (pCTD
->pBaseTypeDescription
!= null)
712 pCTD
= pCTD
->pBaseTypeDescription
;
715 for (int i
= 0; i
< pCTD
->nMembers
; ++i
)
717 if (UString
.UStringToString(pCTD
->ppMemberNames
[i
]) == "Message")
724 int offset
= pCTD
->pMemberOffsets
[pos
];
725 // With the offset within the exception we can get
726 // the message string
727 string message
= UString
.UStringToString(
728 (*(UString
**)((byte *)unoData
+ offset
)));
729 // We need to find a constructor for the exception
730 // that takes the message string. We assume that
731 // the first argument is the message string
732 ConstructorInfo
[] ctorInfos
= managedType
.GetConstructors();
733 ConstructorInfo ctorInfo
= null;
734 // Constructor must at least have 2 params for the base
735 // unoidl.com.sun.star.uno.Exception (String, Object);
737 foreach (ConstructorInfo ci
in ctorInfos
)
739 numArgs
= ci
.GetParameters().Length
;
746 // Prepare parameters for constructor
747 object[] args
= new object[numArgs
];
748 // only initialize the first argument with the
749 // message. All unoidl.<Foo Exception>s are
750 // autogenerated, we know that this is safe.
752 managedObject
= ctorInfo
.Invoke(args
);
755 managedObject
= Activator
.CreateInstance(managedType
);
758 TypeDescriptionReference
**memberTypeRefs
= compTD
->ppTypeRefs
;
759 int *memberOffsets
= compTD
->pMemberOffsets
;
761 if (compTD
->pBaseTypeDescription
!= null)
763 // convert inherited struct
764 // cliObj is passed inout (args in_param, out_param are true), hence the passed
765 // cliObj is used by the callee instead of a newly created struct
766 MapToManaged(ref managedObject
, unoData
,
767 ((TypeDescription
*)compTD
->pBaseTypeDescription
)->pWeakRef
,
771 for (int i
= compTD
->nMembers
- 1; i
>= 0; --i
)
773 TypeDescriptionReference
*memberType
= memberTypeRefs
[i
];
774 string memberName
= UString
.UStringToString(compTD
->ppMemberNames
[i
]);
775 FieldInfo fieldInfo
= managedType
.GetField(memberName
);
776 // special case for Exception.Message. The field has already been
777 // set while constructing cli object
778 if (fieldInfo
== null &&
779 UString
.UStringToString(type
->pTypeName
) == "com.sun.star.uno.Exception")
782 void *p
= (byte *)unoData
+ memberOffsets
[i
];
783 switch (memberType
->eTypeClass
)
786 fieldInfo
.SetValue(managedObject
, (char)*(short *)p
);
788 case TypeClass
.BOOLEAN
:
789 fieldInfo
.SetValue(managedObject
, (*(byte *)p
) != 0);
792 fieldInfo
.SetValue(managedObject
, *(byte *)p
);
794 case TypeClass
.SHORT
:
795 fieldInfo
.SetValue(managedObject
, *(short *)p
);
797 case TypeClass
.UNSIGNED_SHORT
:
798 fieldInfo
.SetValue(managedObject
, *(ushort *)p
);
801 fieldInfo
.SetValue(managedObject
, *(int *)p
);
803 case TypeClass
.UNSIGNED_LONG
:
804 fieldInfo
.SetValue(managedObject
, *(uint *)p
);
806 case TypeClass
.HYPER
:
807 fieldInfo
.SetValue(managedObject
, *(long *)p
);
809 case TypeClass
.UNSIGNED_HYPER
:
810 fieldInfo
.SetValue(managedObject
, *(ulong *)p
);
812 case TypeClass
.FLOAT
:
813 fieldInfo
.SetValue(managedObject
, *(float *)p
);
815 case TypeClass
.DOUBLE
:
816 fieldInfo
.SetValue(managedObject
, *(double *)p
);
820 object managedValue
= null;
821 MapToManaged(ref managedValue
, p
, memberType
, null, false);
822 fieldInfo
.SetValue(managedObject
, managedValue
);
827 managedData
= managedObject
;
830 case TypeClass
.SEQUENCE
:
832 SequencePtr seq
= *(SequencePtr
*)unoData
;
833 int length
= seq
.nElements
;
835 TypeDescription
*td
= null; // FIXME leak
836 TypeDescriptionReference
.GetDescription(&td
, (TypeDescriptionReference
*)type
);
837 TypeDescriptionReference
*elementType
= ((IndirectTypeDescription
*)td
)->pType
;
839 switch (elementType
->eTypeClass
)
843 char[] array
= new char[length
];
844 Marshal
.Copy(seq
.elementsPtr
, array
, 0, length
);
848 case TypeClass
.BOOLEAN
:
850 bool[] array
= new bool[length
];
851 byte *source
= (byte *)seq
.elementsPtr
;
852 if (length
> 0) fixed (bool *arrayPtr
= array
)
854 bool *dest
= arrayPtr
;
855 for (int i
= 0; i
< length
; ++i
)
856 *dest
++ = (*source
++ != 0);
863 byte[] array
= new byte[length
];
864 byte *source
= (byte *)seq
.elementsPtr
;
865 if (length
> 0) fixed (byte *arrayPtr
= array
)
867 byte *dest
= arrayPtr
;
868 for (int i
= 0; i
< length
; ++i
)
874 case TypeClass
.SHORT
:
876 short[] array
= new short[length
];
877 Marshal
.Copy(seq
.elementsPtr
, array
, 0, length
);
881 case TypeClass
.UNSIGNED_SHORT
:
883 ushort[] array
= new ushort[length
];
884 ushort *source
= (ushort *)seq
.elementsPtr
;
885 if (length
> 0) fixed (ushort *arrayPtr
= array
)
887 ushort *dest
= arrayPtr
;
888 for (int i
= 0; i
< length
; ++i
)
896 int[] array
= new int[length
];
897 Marshal
.Copy(seq
.elementsPtr
, array
, 0, length
);
901 case TypeClass
.UNSIGNED_LONG
:
903 uint[] array
= new uint[length
];
904 uint *source
= (uint *)seq
.elementsPtr
;
905 if (length
> 0) fixed (uint *arrayPtr
= array
)
907 uint *dest
= arrayPtr
;
908 for (int i
= 0; i
< length
; ++i
)
914 case TypeClass
.HYPER
:
916 long[] array
= new long[length
];
917 Marshal
.Copy(seq
.elementsPtr
, array
, 0, length
);
921 case TypeClass
.UNSIGNED_HYPER
:
923 ulong[] array
= new ulong[length
];
924 ulong *source
= (ulong *)seq
.elementsPtr
;
925 if (length
> 0) fixed (ulong *arrayPtr
= array
)
927 ulong *dest
= arrayPtr
;
928 for (int i
= 0; i
< length
; ++i
)
934 case TypeClass
.FLOAT
:
936 float[] array
= new float[length
];
937 Marshal
.Copy(seq
.elementsPtr
, array
, 0, length
);
941 case TypeClass
.DOUBLE
:
943 double[] array
= new double[length
];
944 Marshal
.Copy(seq
.elementsPtr
, array
, 0, length
);
948 case TypeClass
.STRING
:
950 string[] array
= new string[length
];
951 for (int i
= 0; i
< length
; ++i
)
953 UString
*us
= ((UString
**)seq
.elementsPtr
)[i
];
954 array
[i
] = UString
.UStringToString(us
);
961 Type
[] array
= new Type
[length
];
962 for (int i
= 0; i
< length
; ++i
)
963 array
[i
] = MapUnoType(((TypeDescriptionReference
**)
964 seq
.elementsPtr
)[i
]);
970 uno
.Any
[] array
= new uno
.Any
[length
];
971 uno
.Binary
.Any
*binAny
= (uno
.Binary
.Any
*)seq
.elementsPtr
;
972 for (int i
= 0; i
< length
; ++i
)
974 object any
= new uno
.Any();
975 MapToManaged(ref any
, (void **)(binAny
+ i
),
976 (TypeDescriptionReference
*)elementType
,
978 array
[i
] = (uno
.Any
)any
;
985 Type enumType
= null;
988 enumType
= info
.GetElementType();
989 // enumType is EnumType[], get EnumType
990 enumType
= enumType
.GetElementType();
993 enumType
= MapUnoType(elementType
);
995 Array array
= Array
.CreateInstance(enumType
, length
);
996 for (int i
= 0; i
< length
; ++i
)
998 array
.SetValue(Enum
.ToObject(enumType
,
999 ((int *)seq
.elementsPtr
)[i
]),
1002 managedData
= array
;
1005 case TypeClass
.STRUCT
:
1006 case TypeClass
.EXCEPTION
:
1008 Array array
= Array
.CreateInstance(MapUnoType(elementType
), length
);
1012 byte *p
= (byte *)seq
.elementsPtr
;
1013 int size
= ((TypeDescription
*)elementType
)->nSize
;
1014 for (int i
= 0; i
< length
; ++i
)
1017 MapToManaged(ref val
, p
+ (size
* i
), elementType
, null, false);
1018 array
.SetValue(val
, i
);
1021 managedData
= array
;
1024 // FIXME verify (says cli_data.cxx)
1025 case TypeClass
.SEQUENCE
:
1027 Array array
= Array
.CreateInstance(
1028 MapUnoType(elementType
), length
);
1031 SequencePtr
*elements
= (SequencePtr
*)seq
.elementsPtr
;
1032 for (int i
= 0; i
< length
; ++i
)
1035 MapToManaged(ref val
, elements
+ i
, elementType
, null, false);
1036 array
.SetValue(val
, i
);
1039 managedData
= array
;
1042 case TypeClass
.INTERFACE
:
1044 Type ifaceType
= MapUnoType(elementType
);
1045 Array array
= Array
.CreateInstance(ifaceType
, length
);
1047 byte *p
= (byte *)seq
.elementsPtr
;
1048 int size
= ((TypeDescription
*)elementType
)->nSize
;
1049 for (int i
= 0; i
< length
; ++i
)
1052 MapToManaged(ref val
, p
+ (size
* i
), elementType
, null, false);
1053 array
.SetValue(val
, i
);
1055 managedData
= array
;
1060 // FIXME throw some exception
1066 case TypeClass
.INTERFACE
:
1068 IntPtr unoI
= new IntPtr(*(void **)unoData
);
1069 if (unoI
!= IntPtr
.Zero
)
1071 TypeDescription
*td
= null; // FIXME leak
1072 TypeDescriptionReference
.GetDescription(&td
, type
);
1073 managedData
= MapUnoToManaged(unoI
, (InterfaceTypeDescription
*)td
);
1081 // FIXME throw some exception
1087 public static Type
MapUnoType(TypeDescription
*TD
)
1089 return MapUnoType(TD
->pWeakRef
);
1092 public static Type
MapUnoType(TypeDescriptionReference
*TD
)
1096 switch(TD
->eTypeClass
)
1098 case TypeClass
.VOID
:
1099 result
= typeof(void);
1101 case TypeClass
.CHAR
:
1102 result
= typeof(char);
1104 case TypeClass
.BOOLEAN
:
1105 result
= typeof(bool);
1107 case TypeClass
.BYTE
:
1108 result
= typeof(byte);
1110 case TypeClass
.SHORT
:
1111 result
= typeof(short);
1113 case TypeClass
.UNSIGNED_SHORT
:
1114 result
= typeof(ushort);
1116 case TypeClass
.LONG
:
1117 result
= typeof(int);
1119 case TypeClass
.UNSIGNED_LONG
:
1120 result
= typeof(uint);
1122 case TypeClass
.HYPER
:
1123 result
= typeof(long);
1125 case TypeClass
.UNSIGNED_HYPER
:
1126 result
= typeof(ulong);
1128 case TypeClass
.FLOAT
:
1129 result
= typeof(float);
1131 case TypeClass
.DOUBLE
:
1132 result
= typeof(double);
1134 case TypeClass
.STRING
:
1135 result
= typeof(string);
1137 case TypeClass
.TYPE
:
1138 result
= typeof(Type
);
1141 result
= typeof(uno
.Any
);
1143 case TypeClass
.ENUM
:
1144 case TypeClass
.STRUCT
:
1145 case TypeClass
.EXCEPTION
:
1146 result
= LoadCliType(TD
->pTypeName
);
1148 case TypeClass
.INTERFACE
:
1149 // special handling for XInterface, since it does not exist in cli.
1150 if (UString
.UStringToString(TD
->pTypeName
) == "com.sun.star.uno.XInterface")
1151 result
= typeof(object);
1153 result
= LoadCliType(TD
->pTypeName
);
1155 case TypeClass
.SEQUENCE
:
1157 TypeDescription
*seqType
= null; // FIXME leak
1158 TypeDescriptionReference
.GetDescription(&seqType
, TD
);
1160 // FIXME do something with TD here?
1161 TypeDescriptionReference
*elementTDRef
=
1162 ((IndirectTypeDescription
*)seqType
)->pType
;
1164 switch (elementTDRef
->eTypeClass
)
1166 case TypeClass
.CHAR
:
1167 result
= Type
.GetType("System.Char[]");
1169 case TypeClass
.BOOLEAN
:
1170 result
= Type
.GetType("System.Boolean[]");
1172 case TypeClass
.BYTE
:
1173 result
= Type
.GetType("System.Byte[]");
1175 case TypeClass
.SHORT
:
1176 result
= Type
.GetType("System.Int16[]");
1178 case TypeClass
.UNSIGNED_SHORT
:
1179 result
= Type
.GetType("System.UInt16[]");
1181 case TypeClass
.LONG
:
1182 result
= Type
.GetType("System.Int32[]");
1184 case TypeClass
.UNSIGNED_LONG
:
1185 result
= Type
.GetType("System.UInt32[]");
1187 case TypeClass
.HYPER
:
1188 result
= Type
.GetType("System.Int64[]");
1190 case TypeClass
.UNSIGNED_HYPER
:
1191 result
= Type
.GetType("System.UInt64[]");
1193 case TypeClass
.FLOAT
:
1194 result
= Type
.GetType("System.Single[]");
1196 case TypeClass
.DOUBLE
:
1197 result
= Type
.GetType("System.Double[]");
1199 case TypeClass
.STRING
:
1200 result
= Type
.GetType("System.String[]");
1202 case TypeClass
.TYPE
:
1203 result
= Type
.GetType("System.Type[]");
1206 case TypeClass
.ENUM
:
1207 case TypeClass
.EXCEPTION
:
1208 case TypeClass
.STRUCT
:
1209 case TypeClass
.INTERFACE
:
1210 case TypeClass
.SEQUENCE
:
1211 result
= LoadCliType(TD
->pTypeName
);
1214 // FIXME can't happen
1221 // FIXME can't happen
1228 public static Type
LoadCliType(UString
* unoName
)
1230 return LoadCliType(MapUnoTypeName(UString
.UStringToString(unoName
)));
1233 public static Type
LoadCliType(string unoName
)
1236 bool isPolymorphic
= false;
1238 string loadName
= unoName
;
1239 int index
= unoName
.IndexOf('<');
1242 loadName
= unoName
.Substring(0, index
);
1243 isPolymorphic
= true;
1246 result
= Type
.GetType(loadName
+ ",cli_uretypes");
1249 result
= Type
.GetType(loadName
+ ",cli_basetypes");
1252 result
= Type
.GetType(loadName
, false);
1256 foreach (Assembly a
in AppDomain
.CurrentDomain
.GetAssemblies())
1258 result
= a
.GetType(loadName
, false);
1265 // FIXME don't use generic Exception type
1266 throw new Exception("A type could not be loaded: " + loadName
);
1269 result
= uno
.PolymorphicType
.GetType(result
, unoName
);
1274 static TypeDescriptionReference
*MapManagedType(Type managedType
)
1276 TypeDescriptionReference
*result
= null;
1277 if (managedType
== null)
1279 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.VOID
);
1280 TypeDescriptionReference
.Acquire(result
);
1284 // check for Enum first,
1285 // because otherwise case System.TypeCode.Int32 applies
1286 if (managedType
.IsEnum
)
1288 UString
* unoTypeName
= MapManagedTypeName(managedType
.FullName
);
1289 TypeDescriptionReference
.New(&result
, TypeClass
.ENUM
, unoTypeName
);
1290 TypeDescriptionReference
.Acquire(result
);
1294 switch (System
.Type
.GetTypeCode(managedType
))
1296 case System
.TypeCode
.Boolean
:
1297 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.BOOLEAN
);
1298 TypeDescriptionReference
.Acquire(result
);
1300 case System
.TypeCode
.Char
:
1301 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.CHAR
);
1302 TypeDescriptionReference
.Acquire(result
);
1304 case System
.TypeCode
.Byte
:
1305 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.BYTE
);
1306 TypeDescriptionReference
.Acquire(result
);
1308 case System
.TypeCode
.Int16
:
1309 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.SHORT
);
1310 TypeDescriptionReference
.Acquire(result
);
1312 case System
.TypeCode
.Int32
:
1313 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.LONG
);
1314 TypeDescriptionReference
.Acquire(result
);
1316 case System
.TypeCode
.Int64
:
1317 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.HYPER
);
1318 TypeDescriptionReference
.Acquire(result
);
1320 case System
.TypeCode
.UInt16
:
1321 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.UNSIGNED_SHORT
);
1322 TypeDescriptionReference
.Acquire(result
);
1324 case System
.TypeCode
.UInt32
:
1325 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.UNSIGNED_LONG
);
1326 TypeDescriptionReference
.Acquire(result
);
1328 case System
.TypeCode
.UInt64
:
1329 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.UNSIGNED_HYPER
);
1330 TypeDescriptionReference
.Acquire(result
);
1332 case System
.TypeCode
.Single
:
1333 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.FLOAT
);
1334 TypeDescriptionReference
.Acquire(result
);
1336 case System
.TypeCode
.Double
:
1337 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.DOUBLE
);
1338 TypeDescriptionReference
.Acquire(result
);
1340 case System
.TypeCode
.String
:
1341 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.STRING
);
1342 TypeDescriptionReference
.Acquire(result
);
1349 string managedTypeName
= managedType
.FullName
;
1350 if (managedTypeName
== "System.Void")
1352 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.VOID
);
1353 TypeDescriptionReference
.Acquire(result
);
1355 else if (managedTypeName
== "System.Type")
1357 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.TYPE
);
1358 TypeDescriptionReference
.Acquire(result
);
1360 else if (managedTypeName
== "uno.Any")
1362 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.ANY
);
1363 TypeDescriptionReference
.Acquire(result
);
1367 UString
* unoTypeName
;
1369 uno
.PolymorphicType poly
= managedType
as uno
.PolymorphicType
;
1371 unoTypeName
= MapManagedTypeName(poly
.PolymorphicName
);
1373 unoTypeName
= MapManagedTypeName(managedTypeName
);
1375 TypeDescription
*td
= null;
1376 TypeDescription
.GetByName(&td
, unoTypeName
);
1379 result
= td
->pWeakRef
;
1380 TypeDescriptionReference
.Acquire(result
);
1381 TypeDescription
.Release(td
);
1388 // FIXME - quite probably we should throw an exception here instead.
1389 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.VOID
);
1390 TypeDescriptionReference
.Acquire(result
);
1396 static string MapUnoTypeName(string typeName
)
1398 StringBuilder buf
= new StringBuilder();
1400 // determine if the type is a sequence and its dimensions
1402 if (typeName
[0] == '[')
1407 if (typeName
[index
++] == ']')
1409 if (typeName
[index
++] != '[')
1412 typeName
= typeName
.Substring(index
- 1);
1418 buf
.Append("System.Boolean");
1421 buf
.Append("System.Char");
1424 buf
.Append("System.Byte");
1427 buf
.Append("System.Int16");
1429 case "unsigned short":
1430 buf
.Append("System.UInt16");
1433 buf
.Append("System.Int32");
1435 case "unsigned long":
1436 buf
.Append("System.UInt32");
1439 buf
.Append("System.Int64");
1441 case "unsigned hyper":
1442 buf
.Append("System.UInt64");
1445 buf
.Append("System.Single");
1448 buf
.Append("System.Double");
1451 buf
.Append("System.String");
1454 buf
.Append("System.Void");
1457 buf
.Append("System.Type");
1459 case "com.sun.star.uno.XInterface":
1460 buf
.Append("System.Object");
1463 buf
.Append("uno.Any");
1466 // put "unoidl." at the beginning
1467 buf
.Append("unoidl.");
1468 // for polymorphic struct types remove the brackets, e.g. mystruct<bool> -> mystruct
1469 buf
.Append(MapUnoPolymorphicName(typeName
));
1474 for ( ; dims
> 0; --dims
)
1477 return buf
.ToString();
1480 /** For example, there is a uno type
1481 com.sun.star.Foo<char, long>.
1482 The values in the type list
1483 are uno types and are replaced by cli types, such as System.Char,
1486 static string MapUnoPolymorphicName(string unoName
)
1488 int startIndex
= unoName
.LastIndexOf('<');
1489 if (startIndex
== -1)
1492 // get the type list within < and >
1493 int endIndex
= unoName
.LastIndexOf('>');
1494 string list
= unoName
.Substring(startIndex
+ 1, endIndex
- startIndex
- 1);
1496 // parse the type list and replace the types with the corresponding CLI types
1497 char[] delimiters
= new char[] { ',' }
;
1498 string[] unoTypes
= list
.Split(delimiters
);
1500 StringBuilder builder
= new StringBuilder(unoName
.Substring(0, startIndex
+ 1));
1502 int typeCount
= unoTypes
.Length
;
1503 for (int i
= 0; i
< typeCount
; ++i
)
1504 builder
.Append(MapUnoTypeName(unoTypes
[i
]));
1506 builder
.Append('>');
1507 return builder
.ToString();
1510 static UString
* MapManagedTypeName(string typeName
)
1515 if ((index
= typeName
.IndexOf("[]")) > 0)
1519 int curIndex
= index
;
1520 while ((curIndex
+ 2) < typeName
.Length
&&
1521 (curIndex
= typeName
.IndexOf("[]", curIndex
+ 2)) > 0)
1524 // get the element name by removing the brackets
1525 typeName
= typeName
.Substring(0, index
);
1528 StringBuilder buf
= new StringBuilder(256);
1529 for (; dims
> 0; --dims
)
1534 case "System.Boolean":
1535 buf
.Append("boolean");
1543 case "System.Int16":
1544 buf
.Append("short");
1546 case "System.UInt16":
1547 buf
.Append("unsigned short");
1549 case "System.Int32":
1552 case "System.UInt32":
1553 buf
.Append("unsigned long");
1555 case "System.Int64":
1556 buf
.Append("hyper");
1558 case "System.UInt64":
1559 buf
.Append("unsigned hyper");
1561 case "System.Single":
1562 buf
.Append("float");
1564 case "System.Double":
1565 buf
.Append("double");
1567 case "System.String":
1568 buf
.Append("string");
1576 case "System.Object":
1577 buf
.Append("com.sun.star.uno.XInterface");
1584 string name
= MapManagedPolymorphicName(typeName
);
1585 int i
= name
.IndexOf('.');
1586 buf
.Append(name
.Substring(i
+ 1));
1591 UString
*rtl_uString
= null;
1592 UString
.NewFromStringBuilder(&rtl_uString
, buf
);
1596 static string MapManagedPolymorphicName(string unoName
)
1598 int startIndex
= unoName
.LastIndexOf('<');
1599 if (startIndex
== -1)
1602 // get the type list withing < and >
1603 int endIndex
= unoName
.LastIndexOf('>');
1604 string list
= unoName
.Substring(startIndex
+ 1, endIndex
- startIndex
- 1);
1606 // parse the type list and replace the types with the corresponding CLI types
1607 char[] delimiters
= new char[] { ',' }
;
1608 string[] unoTypes
= list
.Split(delimiters
);
1610 StringBuilder builder
= new StringBuilder(unoName
.Substring(0, startIndex
+ 1));
1612 int typeCount
= unoTypes
.Length
;
1613 for (int i
= 0; i
< typeCount
; ++i
)
1614 builder
.Append(UString
.UStringToString(MapManagedTypeName(unoTypes
[i
])));
1615 builder
.Append('>');
1616 return builder
.ToString();
1619 [StructLayout(LayoutKind
.Explicit
)]
1620 private unsafe struct largest
1622 [FieldOffset(0)] long n
;
1623 [FieldOffset(0)] double d
;
1624 [FieldOffset(0)] void *p
;
1625 [FieldOffset(0)] uno
.Binary
.Any a
;
1628 // FIXME args[i] must be of same type as return value
1629 public unsafe uno
.Any
CallUno(IntPtr unoInterface
, TypeDescription
*memberTD
,
1630 TypeDescriptionReference
*returnType
, int nParams
,
1631 MethodParameter
*parameters
, object[] args
,
1632 Type
[] argTypes
, out uno
.Any exception
)
1634 int returnSize
= sizeof(largest
);
1636 if (returnType
!= null &&
1637 (returnType
->eTypeClass
== TypeClass
.STRUCT
||
1638 returnType
->eTypeClass
== TypeClass
.EXCEPTION
))
1641 TypeDescription
*td
= null;
1642 TypeDescriptionReference
.GetDescription(&td
, returnType
);
1644 if (td
->nSize
> returnSize
)
1645 returnSize
= td
->nSize
;
1648 // Prepare memory that contains all converted arguments and
1649 // return values. The memory block contains first pointers to
1650 // the arguments which are in the same block For example, 2
1651 // arguments, 1 ret.
1659 // If an argument is larger then struct largest, such as some
1660 // structures, then the pointer points to an extra block of
1661 // memory. The same goes for a big return value.
1662 // FIXME the last sentence is bullshit. Get it deleted from cli_uno ;)
1663 byte *mem
= stackalloc byte[nParams
* sizeof(void *) +
1665 nParams
* sizeof(largest
)];
1667 // array of pointers to args
1668 void **unoArgPtrs
= (void **)mem
;
1671 void *unoRetPtr
= null;
1672 largest
*unoArgs
= (largest
*)(unoArgPtrs
+ nParams
);
1673 if (memberTD
->eTypeClass
!= TypeClass
.INTERFACE_ATTRIBUTE
|| nParams
!= 1)
1675 // If an attribute is set, then unoRet must be null, e.g. void setAttribute(int)
1676 unoRetPtr
= (void *)unoArgs
;
1677 unoArgs
= (largest
*)((byte *)unoRetPtr
+ returnSize
);
1680 for (int i
= 0; i
< nParams
; ++i
)
1682 // FIXME it's a TypeDescriptionReference
1683 TypeDescription
*type
= (TypeDescription
*)parameters
[i
].pTypeRef
;
1685 unoArgPtrs
[i
] = unoArgs
+ i
;
1686 if ((type
->eTypeClass
== TypeClass
.STRUCT
||
1687 type
->eTypeClass
== TypeClass
.EXCEPTION
) &&
1688 (type
->nSize
> sizeof(largest
)))
1690 // stackalloc is only allowed in initializers
1691 byte *bigArgPtr
= stackalloc byte[type
->nSize
];
1693 unoArgPtrs
[i
] = bigArgPtr
;
1696 if (parameters
[i
].bIn
!= 0)
1698 // FIXME error handling
1699 MapToUno(unoArgPtrs
[i
], args
[i
], type
, false /* no assign */);
1703 uno
.Binary
.Any unoExceptionHolder
;
1704 uno
.Binary
.Any
*unoExc
= &unoExceptionHolder
;
1707 uno
.Binary
.Interface
.Dispatch(
1708 unoInterface
, memberTD
, unoRetPtr
, unoArgPtrs
, &unoExc
);
1712 exception
= uno
.Any
.VOID
;
1714 // convert out args, destroy uno args
1715 for (int i
= 0; i
< nParams
; ++i
)
1717 // FIXME it's a TypeDescriptionReference
1718 TypeDescription
*type
= (TypeDescription
*)parameters
[i
].pTypeRef
;
1720 if (parameters
[i
].bOut
!= 0)
1722 // FIXME error handling
1723 MapToManaged(ref args
[i
], unoArgPtrs
[i
], parameters
[i
].pTypeRef
,
1724 argTypes
!= null ? argTypes
[i
] : null, false);
1728 if (type
->eTypeClass
< TypeClass
.DOUBLE
&&
1729 type
->eTypeClass
!= TypeClass
.ENUM
) // no need to destroy these
1730 uno
.Binary
.Data
.Destroy(unoArgPtrs
[i
], type
, null);
1733 if (returnType
!= null && returnType
->eTypeClass
!= TypeClass
.VOID
)
1735 // convert uno return value
1736 object result
= null;
1737 // FIXME error handling
1738 MapToManaged(ref result
, unoRetPtr
, returnType
, null, false);
1739 uno
.Binary
.Data
.Destroy(unoRetPtr
, (TypeDescription
*)returnType
, null);
1740 return new uno
.Any(MapUnoType(returnType
), result
); // FIXME is this correct?
1743 return uno
.Any
.VOID
;
1745 else // exception occured
1747 for (int i
= 0; i
< nParams
; ++i
)
1748 if (parameters
[i
].bIn
!= 0)
1749 uno
.Binary
.Data
.Destroy(unoArgPtrs
[i
], (TypeDescription
*)parameters
[i
].pTypeRef
, null);
1751 // FIXME needs uno.Any vs System.Object clarification
1753 MapToManaged(ref exc
, unoExceptionHolder
.pData
,
1754 unoExceptionHolder
.pType
, null, false);
1755 exception
= new uno
.Any(MapUnoType(unoExceptionHolder
.pType
), exc
);
1756 return uno
.Any
.VOID
;
1759 // FIXME error handling
1762 // FIXME rename, to say what it does, not how it does this
1763 public void RegisterWithCliEnvironment(object managedI
, string oid
)
1765 managedEnvironment
.registerInterface(managedI
, oid
);
1768 public void RegisterWithCliEnvironment(object managedI
, string oid
, Type type
)
1770 managedEnvironment
.registerInterface(managedI
, oid
, type
);
1773 public void RegisterWithUnoEnvironment(ref IntPtr unoInterface
, string oid
, InterfaceTypeDescription
*TD
)
1775 UString
*unoOid
= null;
1776 UString
.NewFromString(&unoOid
, oid
);
1778 uno
.Binary
.Environment
.RegisterInterface(unoEnvironment
, ref unoInterface
, unoOid
, TD
);
1780 UString
.Release(unoOid
);
1783 public void GetInterfaceFromUnoEnvironment(ref IntPtr unoInterface
, UString
* unoOid
, InterfaceTypeDescription
* TD
)
1785 uno
.Binary
.Environment
.GetRegisteredInterface(unoEnvironment
, ref unoInterface
, unoOid
, TD
);
1788 public void RevokeFromUnoEnvironment(IntPtr unoInterface
)
1790 throw new NotImplementedException();
1793 public unsafe IntPtr
CreateManagedProxy(object managedInterface
,
1794 TypeDescription
* td
,
1797 // register original interface
1798 RegisterWithCliEnvironment(managedInterface
,
1799 UString
.UStringToString(oid
),
1800 Bridge
.MapUnoType(td
));
1802 ManagedProxy proxy
= new ManagedProxy(this, managedInterface
, td
, oid
);
1803 GCHandle gchandle
= GCHandle
.Alloc(proxy
);
1805 // create binary uno uno_Interface and register proxy with target environment
1806 IntPtr unoI
= CreateBinaryProxyAndRegister(unoEnvironment
, (IntPtr
)gchandle
,
1809 proxy
.NativeProxy
= unoI
;
1813 [ DllImport("cli_uno", EntryPoint
="cli_uno_environment_createMonoProxyAndRegister") ]
1814 public static unsafe extern IntPtr
CreateBinaryProxyAndRegister(
1815 IntPtr unoEnvironment
,
1817 /* UString */ void* oid
,
1818 /* InterfaceTypeDescription */ void* td
);
1820 public unsafe void CallManaged(object managedI
, Type ifaceType
, MethodInfo method
,
1821 TypeDescriptionReference
* returnType
,
1822 MethodParameter
* parameters
, int nParams
, void* unoRet
,
1823 void** unoArgs
, uno
.Binary
.Any
** unoExc
)
1825 object[] args
= new object[nParams
];
1826 for (int i
= 0; i
< nParams
; ++i
)
1827 if (parameters
[i
].bIn
!= 0)
1828 MapToManaged(ref args
[i
], unoArgs
[i
], parameters
[i
].pTypeRef
, null, false);
1830 object invocationResult
= null;
1833 invocationResult
= method
.Invoke(managedI
, args
);
1835 catch (TargetInvocationException e
)
1837 Exception exc
= e
.InnerException
;
1838 TypeDescription
* td
= null;
1840 TypeDescriptionReference
.GetDescription(&td
, MapManagedType(exc
.GetType()));
1841 void* memExc
= uno
.rtl
.Mem
.Allocate(td
->nSize
);
1842 MapToUno(memExc
, exc
, /* FIXME !!!*/ (TypeDescription
*)td
->pWeakRef
, false);
1843 (*unoExc
)->pType
= td
->pWeakRef
;
1844 (*unoExc
)->pData
= memExc
;
1852 // convert out, in/out params
1853 for (int i
= 0; i
< nParams
; ++i
)
1855 if (parameters
[i
].bOut
!= 0)
1858 unoArgs
[i
], args
[i
], /* FIXME !!! */(TypeDescription
*)parameters
[i
].pTypeRef
,
1859 parameters
[i
].bIn
!= 0 /* assign if inout */);
1860 // FIXME error handling
1865 if (returnType
!= null)
1866 MapToUno(unoRet
, invocationResult
, /* FIXME !!! */(TypeDescription
*)returnType
, false /* no assign */);
1868 // no exception occurred