[Mono-list] Strange behavior with P/Invoke and return values

Paolo Molaro lupus@ximian.com
Thu, 28 Aug 2003 18:05:48 +0200


On 08/25/03 Patrick Hartling wrote:
> I am experimenting with mapping C++ to C# via P/Invoke and Mono 0.26 on 
> Red Hat 8.0, and I have run into something odd when a native function 
> returns a C++ object by value.  From the way it is behaving, it appears 
> that something is going wrong in the allocation of memory on the stack 
> for the return value.
> 
> I have attached some code that demonstrates the problem.  My intent is to 
> use a custom marshaler to make a copy of the return value object in a 
> freshly allocated C# object reference.  (The validity of this technique 
> is what I am evaluating, so it's possible I am going down the wrong road 
> with this.)
[...]
>    [DllImport("return_copy")]
>    [return : MarshalAs(UnmanagedType.CustomMarshaler,
>                        MarshalTypeRef = typeof(ReferenceDataMarshaler))]
>    private static extern ReferenceData Marshal_getReferenceCopy(IntPtr instPtr);

Does your code work under the MS runtime?
I'm not sure it's supposed to work.
ReferenceData in C# is a class, so by default the marshal code in mono
(check metadata/marshal.c) assumes the unmanaged function returns a
pointer. The C++ code, though returns the data by value, so you have a
mismatch. You may try to define a C# struct that matches ReferenceData
and use that as the type returned from Marshal_getReferenceCopy().
In a wrapper you create a ReferenceData obj and copy the fields from the
struct.

lupus

-- 
-----------------------------------------------------------------
lupus@debian.org                                     debian/rules
lupus@ximian.com                             Monkeys do it better