[.net] native vs managed value structs
1. Can a value struct inherit from a native struct?
2. Suppose I have a native structure:
struct Vector3
{
float x, y, z;
};
and I make a corresponding managed version
value struct VectorEx3
{
float x, y, z;
};
If you have a function that takes a pointer to a Vector3 as a parameter, is it okay to cast a VectorEx3 object to it:
VectorEx3 v;
foo( (Vector3*)&v );
I tried it and it worked, but I want to make sure it is defined behavior.
I too find these issues quite baffling in C++\CLI since it doubles the amount of syntax and storage options and then hides a fair amount using implicit interop. Its a bad sign when a new language makes C++ look simple eh?
I was interested enough to create a little test. The outcome for me is that when the "value struct" is passed as a pointer, a conversion operator "conv.i4" is generated in the MSIL. I therefore believe that it will work fine due to implicit interop but at a performance overhead.
Introduction to MSIL : Casts and Conversions
The c++ source:
The MSIL:
I was interested enough to create a little test. The outcome for me is that when the "value struct" is passed as a pointer, a conversion operator "conv.i4" is generated in the MSIL. I therefore believe that it will work fine due to implicit interop but at a performance overhead.
Introduction to MSIL : Casts and Conversions
The c++ source:
struct struct1{ int i;};value struct struct2{ int i;};#pragma unmanagedstruct struct3{ int i;};#pragma managedvoid Increment(struct1 * v) {v->i++;};int main(array<System::String ^> ^args){ struct1 a; struct2 b; struct3 c; a.i = 6; b.i = 9; c.i = 42; Increment((struct1 *)&a); Increment((struct1 *)&b); Increment((struct1 *)&c); return 0;}
The MSIL:
; 28 : struct1 a;; 29 : struct2 b; ldc.i.0 0 ; i32 0x0 stloc.0 ; $T11256 ldloca.s 3 ; _b$ initobj $TypeTok$798720C4$; 30 : struct3 c;; 31 : ; 32 : a.i = 6; ldloca.s 2 ; _a$ ldc.i.6 6 ; i32 0x6 stind.i4 ; 33 : b.i = 9; ldloca.s 3 ; _b$ ldc.i4.s 9 ; i32 0x9 stfld ?i@struct2@@3HA; 34 : c.i = 42; ldloca.s 1 ; _c$ ldc.i4.s 42 ; i32 0x2a stind.i4 ; 35 : ; 36 : Increment((struct1 *)&a); ldloca.s 2 ; _a$ call ?Increment@@$$FYAXPAUstruct1@@@Z; 37 : Increment((struct1 *)&b); ldloca.s 3 ; _b$ conv.i4 call ?Increment@@$$FYAXPAUstruct1@@@Z; 38 : Increment((struct1 *)&c); ldloca.s 1 ; _c$ call ?Increment@@$$FYAXPAUstruct1@@@Z; 39 : ; 40 : Console::WriteLine(L"Hello World");
Oh, and the answer is no to the first question:
error C3830: 'struct2': cannot inherit from 'struct1', value types can only inherit from interface classes
error C3830: 'struct2': cannot inherit from 'struct1', value types can only inherit from interface classes
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement