[Mono-list] Custom Marshalling

2004-10-28 Thread Neale.Ferguson
I've implemented some custom marshalling for an external call so that the parameters 
being sent gets massaged as required by the external routine. In addition, it is 
supposed to massage data after the call. However, while it will do so on the way out, 
it's not being driven the other way. I found that if I specified ref on the 
parameters being passed then the MarshalManagedToNative method will not be driven, if 
I specify nothing or out then neither the ToNative or ToManaged methods are being 
called.

[DllImport(libname, EntryPoint = scumbag)]
private unsafe static extern void scumbag  (ref XXXCB cb,
[MarshalAs(UnmanagedType.CustomMarshaler,
 MarshalTypeRef = typeof (AdaByteBuffer))] XXXBuffer fb,
[MarshalAs(UnmanagedType.CustomMarshaler,
 MarshalTypeRef = typeof (AdaByteBuffer))] XXXBuffer rb,
[MarshalAs(UnmanagedType.CustomMarshaler,
 MarshalTypeRef = typeof (AdaByteBuffer))] XXXBuffer sb,
[MarshalAs(UnmanagedType.CustomMarshaler,
 MarshalTypeRef = typeof (AdaByteBuffer))] XXXBuffer vb,
[MarshalAs(UnmanagedType.CustomMarshaler,
 MarshalTypeRef = typeof (AdaIntBuffer))]  XXXIB ib);


Neale 
___
Mono-list maillist  -  [EMAIL PROTECTED]
http://lists.ximian.com/mailman/listinfo/mono-list


Re: [Mono-list] Custom Marshalling

2004-10-28 Thread Marcus
I'm a little confused by your description. I am not trying to be difficult, 
but you use the pronoun it in many places where the antecedent is unclear. 
Also, the phrase on its way out is not clear.

Perhaps if you demonstrated the problem using a P/Invoke method with fewer 
parameters and explained any problems with in, out, and ref parameters 
separately, I could better understand.

Marcus


On Thursday 28 October 2004 1:12 pm, [EMAIL PROTECTED] wrote:
 I've implemented some custom marshalling for an external call so that the
 parameters being sent gets massaged as required by the external routine. In
 addition, it is supposed to massage data after the call. However, while it
 will do so on the way out, it's not being driven the other way. I found
 that if I specified ref on the parameters being passed then the
 MarshalManagedToNative method will not be driven, if I specify nothing or
 out then neither the ToNative or ToManaged methods are being called.

 [DllImport(libname, EntryPoint = scumbag)]
 private unsafe static extern void scumbag  (ref
 XXXCB cb, [MarshalAs(UnmanagedType.CustomMarshaler,
  MarshalTypeRef = typeof (AdaByteBuffer))]
 XXXBuffer fb, [MarshalAs(UnmanagedType.CustomMarshaler,
  MarshalTypeRef = typeof (AdaByteBuffer))]
 XXXBuffer rb, [MarshalAs(UnmanagedType.CustomMarshaler,
  MarshalTypeRef = typeof (AdaByteBuffer))]
 XXXBuffer sb, [MarshalAs(UnmanagedType.CustomMarshaler,
  MarshalTypeRef = typeof (AdaByteBuffer))]
 XXXBuffer vb, [MarshalAs(UnmanagedType.CustomMarshaler,
  MarshalTypeRef = typeof (AdaIntBuffer))]  XXXIB
 ib);
___
Mono-list maillist  -  [EMAIL PROTECTED]
http://lists.ximian.com/mailman/listinfo/mono-list


RE: [Mono-list] Custom Marshalling

2004-10-28 Thread Neale.Ferguson
I'll attempt to think before I type this time :-)

I have a a C routine I wish to call that takes the following parameters:

typedef struct XXXCB {
short a;
char  b[2];
};

void scumbag(XXXCB *cb, char *v);

for our purposes v is an arbitrarily long string of bytes in the range 0x00-0x7f. 
Depending on the contents of b variable v can be input to or output from the 
function scumbag.

In C# I'd code XXXCB as:

public struct XXXCB {
public short a;
[MarshalAS(UnmanagedType.ByValArray, SizeConst=2)}
public byte[] b;
}

Now, because the variable v can be a different length of each call (up to 32K is 
size) I can't use MarshalAs(UnmanagedType.ByValArray) as mcs demands that SizeConst= 
be coded (using SizeParamIndex= doesn't work, in fact I don't think it's supported).

So what I've done is created a class XXXByteBuffer to Marshal the data using 
ICustomMarshaler.

Therefore, I've coded the call prototype as:

[DllImport(libname, EntryPoint = scumbag)]
private static extern void scumbag (ref XXXCB cb,
  [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (XXXByteBuffer))] 
v);

I created the necessary methods (like ManagedToNative and NativeToManaged) in 
XXXByteBuffer. When I call scumbag using parameters conforming to the above prototype 
the ManagedToNative method is being driven prior to the call but NativeToManaged is 
not being called on the return. If I change the prototype to specify ref v or out 
v then neither method is being driven.

Neale

-Original Message-
I'm a little confused by your description. I am not trying to be difficult, 
but you use the pronoun it in many places where the antecedent is unclear. 
Also, the phrase on its way out is not clear.

Perhaps if you demonstrated the problem using a P/Invoke method with fewer 
parameters and explained any problems with in, out, and ref parameters 
separately, I could better understand.
___
Mono-list maillist  -  [EMAIL PROTECTED]
http://lists.ximian.com/mailman/listinfo/mono-list


RE: [Mono-list] Custom Marshalling

2004-10-28 Thread Jonathan Pryor
You're making this far too difficult on yourself.  See below.

On Thu, 2004-10-28 at 19:57, [EMAIL PROTECTED] wrote:
 I'll attempt to think before I type this time :-)
 
 I have a a C routine I wish to call that takes the following parameters:
 
 typedef struct XXXCB {
 short a;
 char  b[2];
 };
 
 void scumbag(XXXCB *cb, char *v);

snip/

 In C# I'd code XXXCB as:
 
 public struct XXXCB {
   public short a;
   [MarshalAS(UnmanagedType.ByValArray, SizeConst=2)}
   public byte[] b;
 }

Good declaration.

 Now, because the variable v can be a different length of each call
 (up to 32K is size) I can't use MarshalAs(UnmanagedType.ByValArray) as
 mcs demands that SizeConst= be coded (using SizeParamIndex= doesn't
 work, in fact I don't think it's supported).

There's a bigger problem: ByValArray doesn't mean what you think it
does.  At least, not entirely.

ByValArray means that it's a contiguous blob of memory, which is why you
used it in your XXXCB structure declaration -- you needed to specify the
size of b.  Perfectly natural.

However, it means the *same thing* no matter where it's applied.  So
applied to a method argument, it means push a blob of data SizeConst
bytes onto the stack).  This is NOT what C does; C always pushes a
*pointer* to an array onto the stack.  Compare these two (C-like)
declarations:

// ByValArray equivalent
void scumbag (XXXCB *cb, struct {char data[SOME_LENGTH];} v);

// LPArray equivalent:
void scumbag (XXXCB *cb, char *v);

The first one probably isn't valid C, and certainly isn't what you want
when invoking existing C code (but may be useful when dealing with other
languages).

Obviously, you don't want ByValArray for method arguments.  You want
LPArray.  Fortunately, this is the default, and marshals the number of
elements inside the array:

[DllImport (libname)]
private static extern void scumbag (ref XXXCB cb, byte[] v);

Usage is straight-forward:

XXXCB cb = new XXXCB();
scumbag (ref cb, Encoding.ASCII.GetBytes (this is my v arg1));
scumbag (ref cb, Encoding.ASCII.GetBytes (this is another v));

Consequently, you don't need the custom marshaler.

 - Jon


___
Mono-list maillist  -  [EMAIL PROTECTED]
http://lists.ximian.com/mailman/listinfo/mono-list


Re: [Mono-list] Custom marshalling

2004-08-05 Thread Marcus
Unfortunately, UnmanagedMarshal.DefineCustom is a Mono-only class and not part 
of .NET. The normal .NET mechanism is to create a custom attribute using 
CustomAttributeBuilder to obtain an instance of MarshalAsAttribute with the 
custom marshaler specified. That does not seem to work under Mono.

It is possible to implement custom marshalers without having to use 
reflection, as long as you know what what types you want to marshal to what 
at compile time. 

public class MyMarshal: ICustomMarshaler {...}

private static extern void PrintObject(
 [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef =
typeof(MyMarshal ) )] object o );

On Sunday 25 July 2004 5:12 pm, Alan Jenkins wrote:
 As far as I can tell, Mono supports custom marshalling outside of function
 calls (like PInvoke),  - ie using Marshal.StructToPtr and PtrToStruct, but
 you have to use UnmanagedMarshal.DefineCustom, which would involve
 reflection of some sort - possibly creating your class with custom
 marshalled fields by reflection.

 Does UnmanagedMarshal.DefineCustom work?
 Is it efficient (as far as custom marshalling can be)?
 Is it supported (or undocumented and likely to disappear/break)?

 Would it be (technically) possible to access its functionality through an
 attribute, in the same way that non-custom marshalling is done?
 Is this likely to happen?
___
Mono-list maillist  -  [EMAIL PROTECTED]
http://lists.ximian.com/mailman/listinfo/mono-list


[Mono-list] Custom marshalling

2004-07-25 Thread Alan Jenkins
As far as I can tell, Mono supports custom marshalling outside of function 
calls (like PInvoke),  - ie using Marshal.StructToPtr and PtrToStruct, but 
you have to use UnmanagedMarshal.DefineCustom, which would involve reflection 
of some sort - possibly creating your class with custom marshalled fields by 
reflection.

Does UnmanagedMarshal.DefineCustom work?
Is it efficient (as far as custom marshalling can be)?
Is it supported (or undocumented and likely to disappear/break)?

Would it be (technically) possible to access its functionality through an 
attribute, in the same way that non-custom marshalling is done?  
Is this likely to happen?

Alan

___
Mono-list maillist  -  [EMAIL PROTECTED]
http://lists.ximian.com/mailman/listinfo/mono-list