/
marshal9.cs
102 lines (80 loc) · 2.46 KB
/
marshal9.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// A demonstration of a custom marshaler that marshals
// unmanaged to managed data.
using System;
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)
{
Console.WriteLine ("GetInstance called");
return new MyMarshal ();
}
public void CleanUpManagedData (object managedObj)
{
Console.WriteLine ("CleanUpManagedData called");
}
public void CleanUpNativeData (IntPtr pNativeData)
{
Console.WriteLine("CleanUpNativeData called");
if (pNativeData != IntPtr.Zero) {
IntPtr realPtr = new IntPtr (pNativeData.ToInt64 () - Marshal.SizeOf (typeof (int)));
Marshal.FreeHGlobal (realPtr);
}
}
// 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 4;
}
public IntPtr MarshalManagedToNative (object managedObj)
{
int number;
IntPtr ptr;
try {
number = Convert.ToInt32 (managedObj);
ptr = Marshal.AllocHGlobal (8);
Marshal.WriteInt32 (ptr, 0);
Marshal.WriteInt32 (new IntPtr (ptr.ToInt64 () + Marshal.SizeOf (typeof(int))), number);
return new IntPtr (ptr.ToInt64 () + Marshal.SizeOf (typeof (int)));
} catch {
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)
{
return "*" + Marshal.PtrToStringAnsi( pNativeData ) + "*";
}
}
public class Testing
{
[DllImport("libtest")]
private static extern int printInt([MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(MyMarshal ))] object number );
[DllImport("libtest")]
private static extern void callFunction (Delegate d);
delegate void Del ([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(MyMarshal))] string x);
public static void TestMethod (string s)
{
Console.WriteLine("s = {0}", s);
if (s != "*ABC*")
throw new Exception ("received wrong value");
}
public static int Main()
{
object x = 5;
if (printInt (x) != 6)
return 1;
Del del = new Del (TestMethod);
callFunction (del);
return 0;
}
}