[Mono-bugs] [Bug 62610][Wis] Changed - Attaching MarshalAsAttribute via SRE does not work as expected
bugzilla-daemon@bugzilla.ximian.com
bugzilla-daemon@bugzilla.ximian.com
Fri, 6 Aug 2004 03:30:31 -0400 (EDT)
Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.
Changed by mathpup@mylinuxisp.com.
http://bugzilla.ximian.com/show_bug.cgi?id=62610
--- shadow/62610 2004-08-06 03:28:12.000000000 -0400
+++ shadow/62610.tmp.23323 2004-08-06 03:30:31.000000000 -0400
@@ -1,14 +1,14 @@
Bug#: 62610
Product: Mono: Class Libraries
Version: unspecified
-OS:
+OS: unknown
OS Details:
Status: NEW
Resolution:
-Severity:
+Severity: Unknown
Priority: Wishlist
Component: CORLIB
AssignedTo: mono-bugs@ximian.com
ReportedBy: mathpup@mylinuxisp.com
QAContact: mono-bugs@ximian.com
TargetMilestone: ---
@@ -65,6 +65,202 @@
How often does this happen?
Always
Additional Information:
+
+------- Additional Comments From mathpup@mylinuxisp.com 2004-08-06 03:30 -------
+The test case is a bit long because of the setup required in using
+SRE...
+
+custom.cs:
+
+using System;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.InteropServices;
+
+
+public class MyMarshal: ICustomMarshaler
+{
+
+ // GetInstance() is not part of ICustomMarshaler, but
+ // custom marshalers are required to implement this
+ // method.
+ public static ICustomMarshaler GetInstance( string s )
+ {
+ return new MyMarshal();
+ }
+
+
+ public void CleanUpManagedData( object managedObj )
+ {
+ }
+
+
+ public void CleanUpNativeData( IntPtr pNativeData )
+ {
+ }
+
+
+ // I really do not understand the purpose of this method
+ // or went it would be called. In fact, Rotor never seems
+ // to call it.
+ public int GetNativeDataSize()
+ {
+ Console.WriteLine("GetNativeDataSize() called");
+ return 0;
+ }
+
+
+ // No marshaling in this direction in this demo.
+ public IntPtr MarshalManagedToNative( object managedObj )
+ {
+ Console.WriteLine("MarshalManagedToNative() not
+implemented");
+ return IntPtr.Zero;
+ }
+
+
+ // Convert a pointer to unmanaged data into a System.Object.
+ // This method simply converts the unmanaged Ansi C-string
+ // into a System.String and surrounds it with asterisks
+ // to differentiate it from the default marshaler.
+ public object MarshalNativeToManaged( IntPtr pNativeData )
+ {
+ Console.WriteLine("MarshalNativeToManaged()");
+ return "*" + Marshal.PtrToStringAnsi( pNativeData ) + "*";
+ }
+}
+
+
+
+public class Testing
+{
+ public static void Method(string value)
+ {
+ Console.WriteLine( "Method( {0} )", value );
+ }
+
+
+ [DllImport("libtest.so", CharSet=CharSet.Ansi )]
+ private static extern void DoCallback( string value );
+
+
+ [DllImport("libtest.so")]
+ private static extern void RegisterCallback( Delegate d );
+
+
+ public static void Main()
+ {
+ AssemblyName asmName = new AssemblyName();
+ asmName.Name = "DynamicAssembly";
+
+
+ AssemblyBuilder asmBuilder =
+ AppDomain.CurrentDomain.DefineDynamicAssembly(
+ asmName, AssemblyBuilderAccess.Run );
+
+ ModuleBuilder modBuilder =
+asmBuilder.DefineDynamicModule( "DynamicModule" );
+
+ TypeBuilder typeBuilder = modBuilder.DefineType( "MyType",
+ TypeAttributes.Public | TypeAttributes.Class |
+TypeAttributes.Sealed,
+ typeof( System.MulticastDelegate ) );
+
+ ConstructorBuilder cb = typeBuilder.DefineConstructor(
+ MethodAttributes.Public | MethodAttributes.HideBySig |
+ MethodAttributes.RTSpecialName |
+MethodAttributes.SpecialName,
+ CallingConventions.Standard,
+ new Type[] { typeof(Object), typeof (IntPtr) } );
+
+ cb.SetImplementationFlags( MethodImplAttributes.Runtime );
+
+ MethodBuilder mb = typeBuilder.DefineMethod(
+ "Invoke",
+ MethodAttributes.Public | MethodAttributes.Virtual |
+MethodAttributes.HideBySig,
+ typeof(void),
+ new Type[] { typeof(string) } );
+
+ ParameterBuilder pb = mb.DefineParameter( 1,
+ParameterAttributes.HasFieldMarshal |
+ ParameterAttributes.In, null );
+
+ // We need to attach the attribute to the parameter
+the attribute
+ // [MarshalAs(UnmanagedType.CustomMarshaler,
+MarshalTypeRef = typeof(MyMarshal)]
+
+ // This does not work in Mono
+
+ CustomAttributeBuilder customAttrBuilder =
+ new CustomAttributeBuilder(
+
+typeof( MarshalAsAttribute ).GetConstructor( new Type[]
+{ typeof( UnmanagedType) } ),
+ new object[]
+{ UnmanagedType.CustomMarshaler },
+ new FieldInfo[]
+{ typeof(MarshalAsAttribute).GetField("MarshalTypeRef") },
+ new object[] { typeof(MyMarshal) } );
+
+ pb.SetCustomAttribute( customAttrBuilder );
+
+ // So instead we have to use this non-portable
+version
+
+//
+pb.SetMarshal( UnmanagedMarshal.DefineCustom( typeof( MyMarshal ),
+"", "MyMarshal", Guid.Empty ) );
+
+ mb.SetImplementationFlags( MethodImplAttributes.Runtime );
+
+
+
+ Type myDelegateType = typeBuilder.CreateType();
+
+ Delegate d = Delegate.CreateDelegate( myDelegateType,
+ typeof( Testing ), "Method" );
+
+ RegisterCallback( d );
+
+ // DoCallback itself gets standard marshaling, so
+unmanaged
+ // code receives a traditional null-terminated
+C-string
+ DoCallback( "Orange" );
+
+// d.DynamicInvoke( new object[] { 8 } );
+ }
+
+}
+
+
+custom.c:
+
+#include <stdio.h>
+
+
+typedef void (*stringFunction)(char*);
+
+stringFunction functionPtr;
+
+
+void RegisterCallback( stringFunction f )
+{
+ printf("Registered\n");
+ functionPtr = f;
+}
+
+
+void DoCallback( char* value )
+{
+ printf("DoCallback\n");
+ functionPtr(value);
+}
+
+
+