using System;
using System.Reflection;
using System.Threading;
using System.Runtime.InteropServices;
namespace TestTwoDomainsAndSingeThread
{
//[StructLayout(LayoutKind.Explicit)]
public unsafe struct Variant
{
//[FieldOffset(0)]
public ushort vt;
//[FieldOffset(0)]
public ushort wReserved1;
//[FieldOffset(0)]
public ushort wReserved2;
//[FieldOffset(0)]
public ushort wReserved3;
//[FieldOffset(0)]
public IntPtr bstrVal;
//[FieldOffset(0)]
public Int32 data01;
//[FieldOffset(0)]
public Int32 data02;
}
public class Worker : MarshalByRefObject
{
public unsafe IntPtr GetIntPtrForVariant()
{
Variant v = new Variant();
IntPtr pNative = Marshal.AllocHGlobal(Marshal.SizeOf(v));
return pNative;
}
public unsafe object GetDoubleFromAnotherDomain()
{
double obj = 3.14;
AppDomain yad = AppDomain.CreateDomain("Yet another domain");
Worker remoteWorker = (Worker)yad.CreateInstanceAndUnwrap(
typeof(Worker).Assembly.FullName,
typeof(Worker).FullName);
IntPtr pNative = remoteWorker.GetIntPtrForVariant();
Marshal.GetNativeVariantForObject(obj, pNative);
object o = Marshal.GetObjectForNativeVariant(pNative);
return o;
}
}
public class Test
{
static unsafe void Main(string[] args)
{
double obj = 3.14;
AppDomain ad = AppDomain.CreateDomain("New domain");
Worker remoteWorker = (Worker)ad.CreateInstanceAndUnwrap(
typeof(Worker).Assembly.FullName,
typeof(Worker).FullName);
IntPtr pNative = remoteWorker.GetIntPtrForVariant();
Marshal.GetNativeVariantForObject(obj, pNative);
Variant result = (Variant)Marshal.PtrToStructure(pNative, typeof(Variant));
Console.WriteLine("VarEnum.VT_R8 name from default domain: " + VarEnum.VT_R8);
Console.WriteLine("Result of (VarEnum)result.vt from another domain: " + (VarEnum)result.vt);
if (VarEnum.VT_R8 != (VarEnum)result.vt)
{
Console.WriteLine("Testcase failed");
} else {
Console.WriteLine("Testcase passed");
}
AppDomain ndfD = AppDomain.CreateDomain("New domain for double");
Worker remoteWorker2 = (Worker)ndfD.CreateInstanceAndUnwrap(
typeof(Worker).Assembly.FullName,
typeof(Worker).FullName);
object o = remoteWorker2.GetDoubleFromAnotherDomain();
Console.WriteLine("3.14 value from default domain: " + obj.ToString());
Console.WriteLine("3.14 value from remote domain: " + o);
if (obj.ToString() != o.ToString())
{
Console.WriteLine("Testcase failed");
} else {
Console.WriteLine("Testcase passed");
}
Console.WriteLine("Obj value cast: " + *((ulong*)&obj));
Console.WriteLine("Unwound variant value cast: " + *((ulong*)&result.bstrVal));
Console.ReadLine();
}
}
}