struct SeqClass
{
- int a;
+ int a;
bool b;
char* str;
};
struct ExpClass
{
- int a;
- int extra; //padding needs to be added here as we have added 8 byte offset.
- union
- {
- int i;
- BOOL b;
- double d;
- } udata;
+ int a;
+ int padding; //padding needs to be added here as we have added 8 byte offset.
+ union
+ {
+ int i;
+ BOOL b;
+ double d;
+ } udata;
};
struct BlittableClass
};
extern "C"
-DLL_EXPORT BOOL STDMETHODCALLTYPE SimpleSeqLayoutClassByRef(SeqClass *p)
+DLL_EXPORT BOOL STDMETHODCALLTYPE SimpleSeqLayoutClassByRef(SeqClass* p)
{
if((p->a != 0) || (p->b) || strcmp(p->str, "before") != 0)
{
- printf("\np->a=%d, p->b=%s, p->str=%s", p->a, p->b ? "true" : "false", p->str);
+ printf("FAIL: p->a=%d, p->b=%s, p->str=%s\n", p->a, p->b ? "true" : "false", p->str);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+extern "C"
+DLL_EXPORT BOOL STDMETHODCALLTYPE SimpleExpLayoutClassByRef(ExpClass* p)
+{
+ if((p->a != 0) || (p->udata.i != 10))
+ {
+ printf("FAIL: p->a=%d, p->udata.i=%d\n",p->a,p->udata.i);
return FALSE;
}
return TRUE;
}
extern "C"
-DLL_EXPORT BOOL STDMETHODCALLTYPE SimpleBlittableSeqLayoutClassByRef(BlittableClass *p)
+DLL_EXPORT BOOL STDMETHODCALLTYPE SimpleBlittableSeqLayoutClassByRef(BlittableClass* p)
{
if(p->a != 10)
{
- printf("\np->a=%d", p->a);
+ printf("FAIL: p->a=%d\n", p->a);
return FALSE;
}
return TRUE;
}
extern "C"
-DLL_EXPORT BOOL STDMETHODCALLTYPE SimpleExpLayoutClassByRef(ExpClass *p)
+DLL_EXPORT BOOL STDMETHODCALLTYPE SimpleBlittableSeqLayoutClassByOutAttr(BlittableClass* p)
{
- if((p->a != 0) || (p->udata.i != 10))
- {
- printf("\np->a=%d, p->udata.i=%d\n",p->a,p->udata.i);
- return FALSE;
- }
- return TRUE;
+ if(!SimpleBlittableSeqLayoutClassByRef(p))
+ return FALSE;
+
+ p->a++;
+ return TRUE;
}
-extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE SimpleNestedLayoutClassByValue(NestedLayoutClass v)
+extern "C"
+DLL_EXPORT BOOL STDMETHODCALLTYPE SimpleNestedLayoutClassByValue(NestedLayoutClass v)
{
return SimpleSeqLayoutClassByRef(&v.str);
}
-extern "C" DLL_EXPORT void __cdecl Invalid(...)
+extern "C"
+DLL_EXPORT void __cdecl Invalid(...)
{
}
{
a = _a;
b = _b;
- str = String.Concat(_str, "");
+ str = string.Concat(_str, "");
}
}
c = 0;
b = bnum;
}
- }
+ }
public enum DialogResult
{
Cancel = 2
}
-
[StructLayout(LayoutKind.Sequential)]
public class Blittable
{
public SeqClass value;
}
-
[StructLayout(LayoutKind.Sequential)]
public class RecursiveTestClass
{
private static extern bool SimpleExpLayoutClassByRef(ExpClass p);
[DllImport("LayoutClassNative")]
- private static extern bool SimpleNestedLayoutClassByValue(NestedLayout p);
+ private static extern bool SimpleBlittableSeqLayoutClassByRef(Blittable p);
[DllImport("LayoutClassNative")]
- private static extern bool SimpleBlittableSeqLayoutClassByRef(Blittable p);
+ private static extern bool SimpleBlittableSeqLayoutClassByOutAttr([Out] Blittable p);
+
+ [DllImport("LayoutClassNative")]
+ private static extern bool SimpleNestedLayoutClassByValue(NestedLayout p);
[DllImport("LayoutClassNative", EntryPoint = "Invalid")]
private static extern void RecursiveNativeLayoutInvalid(RecursiveTestStruct str);
- public static bool SequentialClass()
+ public static void SequentialClass()
{
- string s = "before";
- bool retval = true;
- SeqClass p = new SeqClass(0, false, s);
-
- TestFramework.BeginScenario("Test #1 Pass a sequential layout class.");
-
- try
- {
- retval = SimpleSeqLayoutClassByRef(p);
-
- if (retval == false)
- {
- TestFramework.LogError("01", "PInvokeTests->SequentialClass : Unexpected error occured on unmanaged side");
- return false;
- }
- }
- catch (Exception e)
- {
- TestFramework.LogError("04", "Unexpected exception: " + e.ToString());
- retval = false;
- }
+ Console.WriteLine($"Running {nameof(SequentialClass)}...");
- return retval;
+ string s = "before";
+ var p = new SeqClass(0, false, s);
+ Assert.IsTrue(SimpleSeqLayoutClassByRef(p));
}
- public static bool ExplicitClass()
+ public static void ExplicitClass()
{
- ExpClass p;
- bool retval = false;
-
- TestFramework.BeginScenario("Test #2 Pass an explicit layout class.");
-
- try
- {
- p = new ExpClass(DialogResult.None, 10);
- retval = SimpleExpLayoutClassByRef(p);
-
- if (retval == false)
- {
- TestFramework.LogError("01", "PInvokeTests->ExplicitClass : Unexpected error occured on unmanaged side");
- return false;
- }
+ Console.WriteLine($"Running {nameof(ExplicitClass)}...");
- }
- catch (Exception e)
- {
- TestFramework.LogError("03", "Unexpected exception: " + e.ToString());
- retval = false;
- }
-
- return retval;
+ var p = new ExpClass(DialogResult.None, 10);
+ Assert.IsTrue(SimpleExpLayoutClassByRef(p));
}
- public static bool BlittableClass()
+ public static void BlittableClass()
{
- bool retval = true;
- Blittable p = new Blittable(10);
+ Console.WriteLine($"Running {nameof(BlittableClass)}...");
- TestFramework.BeginScenario("Test #3 Pass a blittable sequential layout class.");
-
- try
- {
- retval = SimpleBlittableSeqLayoutClassByRef(p);
+ Blittable p = new Blittable(10);
+ Assert.IsTrue(SimpleBlittableSeqLayoutClassByRef(p));
+ }
- if (retval == false)
- {
- TestFramework.LogError("01", "PInvokeTests->Blittable : Unexpected error occured on unmanaged side");
- return false;
- }
- }
- catch (Exception e)
- {
- TestFramework.LogError("04", "Unexpected exception: " + e.ToString());
- retval = false;
- }
+ public static void BlittableClassByOutAttr()
+ {
+ Console.WriteLine($"Running {nameof(BlittableClassByOutAttr)}...");
- return retval;
+ int a = 10;
+ int expected = a + 1;
+ Blittable p = new Blittable(a);
+ Assert.IsTrue(SimpleBlittableSeqLayoutClassByOutAttr(p));
+ Assert.AreEqual(expected, p.a);
}
-
- public static bool NestedLayoutClass()
+
+ public static void NestedLayoutClass()
{
+ Console.WriteLine($"Running {nameof(NestedLayoutClass)}...");
+
string s = "before";
- bool retval = true;
- SeqClass p = new SeqClass(0, false, s);
- NestedLayout target = new NestedLayout
+ var p = new SeqClass(0, false, s);
+ var target = new NestedLayout
{
value = p
};
+ Assert.IsTrue(SimpleNestedLayoutClassByValue(target));
+ }
- TestFramework.BeginScenario("Test #4 Nested sequential layout class in a structure.");
-
- try
- {
- retval = SimpleNestedLayoutClassByValue(target);
-
- if (retval == false)
- {
- TestFramework.LogError("01", "PInvokeTests->NestedLayoutClass : Unexpected error occured on unmanaged side");
- return false;
- }
- }
- catch (Exception e)
- {
- TestFramework.LogError("04", "Unexpected exception: " + e.ToString());
- retval = false;
- }
+ public static void RecursiveNativeLayout()
+ {
+ Console.WriteLine($"Running {nameof(RecursiveNativeLayout)}...");
- return retval;
+ Assert.Throws<TypeLoadException>(() => RecursiveNativeLayoutInvalid(new RecursiveTestStruct()));
}
- public static bool RecursiveNativeLayout()
+ public static int Main(string[] argv)
{
- TestFramework.BeginScenario("Test #5 Structure with field of nested layout class with field of containing structure.");
-
try
{
- RecursiveNativeLayoutInvalid(new RecursiveTestStruct());
+ SequentialClass();
+ ExplicitClass();
+ BlittableClass();
+ BlittableClassByOutAttr();
+ NestedLayoutClass();
+ RecursiveNativeLayout();
}
- catch (TypeLoadException)
+ catch (Exception e)
{
- return true;
+ Console.WriteLine($"Test Failure: {e}");
+ return 101;
}
- return false;
+ return 100;
}
-
- public static int Main(string[] argv)
- {
- bool retVal = true;
-
- retVal = retVal && SequentialClass();
- retVal = retVal && ExplicitClass();
- retVal = retVal && BlittableClass();
- retVal = retVal && NestedLayoutClass();
- retVal = retVal && RecursiveNativeLayout();
-
- return (retVal ? 100 : 101);
- }
-
-
}
}