[c++/CLI] What does EXACTLY happen when I compile a native classwith CLR ?

B

bonk

Hello,

I am currently trying to wrap my head around what actually happens when
I compile a normal (native) c++ class with the /CLR Flag in Visual C++
2005 (C++/CLI).

Suppose I have the following class deklared in c++:

// #pragma managed or #pragma unmanaged
// does not seem to make any differnce here
class MyNativeClass
{
public:
int iValue;
public:
void DoSomething(double param)
{
// do something here
}
virtual ~MyNativeClass();
};

If compile that with /CLR we get the follow typedenfintion in the
Assembly (IL)

..class private sequential ansi sealed beforefieldinit MyNativeClass
extends [mscorlib]System.ValueType
{
.custom instance void
[mscorlib]System.Runtime.CompilerServices.NativeCppClassAttribute::.ctor()
.custom instance void
[Microsoft.VisualC]Microsoft.VisualC.MiscellaneousBitsAttribute::.ctor(int32)
= ( int32(0x00000040) )
.custom instance void
[Microsoft.VisualC]Microsoft.VisualC.DebugInfoInPDBAttribute::.ctor()
}

Now where did the Members (iValue and DoSomething) of that Type go?
Not only that they vanished, none of the Attributes listed here hints
where the CLR has to look for the Method implemenetation or for iVlaue.
Are the members compiled to IL too? If so where do I find them? Or are
they compiled to machinecode? That can't be, sinc it is possible to
compile that class with /CLR:pure too and as far as I understand
/CLR:pure prohibits machinecode. How does the CLR know where to look for
the members?
 
B

bonk

Here is an example of what IL is actually generated when I call acess
those members. Now is anyone able to explain what actually happens here?

[c++/CLI]
int main(array<System::String ^> ^args)
{
MyNativeClass* nc = new MyNativeClass();
nc->DoSomething(0xbadf00d);
nc->iValue=0xfade;
}

[disassembled to C#]
internal static unsafe int main(string[] args)
{
MyNativeClass* classPtr2 = @new(8);
MyNativeClass* classPtr1 = (classPtr2 == null) ? null :
((MyNativeClass*) MyNativeClass.{ctor}((MyNativeClass* modopt(IsConst)
modopt(IsConst)) classPtr2));
MyNativeClass.DoSomething((MyNativeClass* modopt(IsConst)
modopt(IsConst)) classPtr1, 69);
*(((int*) (classPtr1 + 4))) = 0x60;
return 0;
}

[disassembled to IL]
..method assembly static int32 main(string[] args) cil managed
{
// Code Size: 43 byte(s)
.maxstack 2
.locals (
MyNativeClass* classPtr1,
MyNativeClass* classPtr2)
L_0000: ldc.i4.8
L_0001: call void*
modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl)
<Module>::new(unsigned int32)
L_0006: stloc.1
L_0007: ldloc.1
L_0008: brfalse.s L_0012
L_000a: ldloc.1
L_000b: call MyNativeClass*
modopt([mscorlib]System.Runtime.CompilerServices.CallConvThiscall)
<Module>::MyNativeClass.{ctor}(MyNativeClass*
modopt([mscorlib]System.Runtime.CompilerServices.IsConst)
modopt([mscorlib]System.Runtime.CompilerServices.IsConst))
L_0010: br.s L_0013
L_0012: ldc.i4.0
L_0013: stloc.0
L_0014: ldloc.0
L_0015: ldc.r8 69
L_001e: call void
modopt([mscorlib]System.Runtime.CompilerServices.CallConvThiscall)
<Module>::MyNativeClass.DoSomething(MyNativeClass*
modopt([mscorlib]System.Runtime.CompilerServices.IsConst)
modopt([mscorlib]System.Runtime.CompilerServices.IsConst), float64)
L_0023: ldloc.0
L_0024: ldc.i4.4
L_0025: add
L_0026: ldc.i4.s 96
L_0028: stind.i4
L_0029: ldc.i4.0
L_002a: ret
}

Hello,

I am currently trying to wrap my head around what actually happens when
I compile a normal (native) c++ class with the /CLR Flag in Visual C++
2005 (C++/CLI).

Suppose I have the following class deklared in c++:

// #pragma managed or #pragma unmanaged
// does not seem to make any differnce here
class MyNativeClass
{
public:
int iValue;
public:
void DoSomething(double param)
{
// do something here
}
virtual ~MyNativeClass();
};

If compile that with /CLR we get the follow typedenfintion in the
Assembly (IL)

.class private sequential ansi sealed beforefieldinit MyNativeClass
extends [mscorlib]System.ValueType
{
.custom instance void
[mscorlib]System.Runtime.CompilerServices.NativeCppClassAttribute::.ctor()
.custom instance void
[Microsoft.VisualC]Microsoft.VisualC.MiscellaneousBitsAttribute::.ctor(int32)
= ( int32(0x00000040) )
.custom instance void
[Microsoft.VisualC]Microsoft.VisualC.DebugInfoInPDBAttribute::.ctor()
}

Now where did the Members (iValue and DoSomething) of that Type go?
Not only that they vanished, none of the Attributes listed here hints
where the CLR has to look for the Method implemenetation or for iVlaue.
Are the members compiled to IL too? If so where do I find them? Or are
they compiled to machinecode? That can't be, sinc it is possible to
compile that class with /CLR:pure too and as far as I understand
/CLR:pure prohibits machinecode. How does the CLR know where to look for
the members?
 
C

Carl Daniel [VC++ MVP]

bonk said:
Hello,

I am currently trying to wrap my head around what actually happens
when I compile a normal (native) c++ class with the /CLR Flag in Visual
C++
2005 (C++/CLI).
[ snipped example code ]

Now where did the Members (iValue and DoSomething) of that Type go?
Not only that they vanished, none of the Attributes listed here hints
where the CLR has to look for the Method implemenetation or for
iVlaue. Are the members compiled to IL too? If so where do I find them? Or
are
they compiled to machinecode? That can't be, sinc it is possible to
compile that class with /CLR:pure too and as far as I understand
/CLR:pure prohibits machinecode. How does the CLR know where to look
for the members?

The CLR knows absolutely nothing about the class beyond how much memory it
occupies. All of the member functions are compiled to IL that uses
burned-in offsets to access the fields of the class. Such classes are
accessible only from C++ since they're lacking CLR metadata to describe the
fields, properties and methods of the class. In this mode, you can think of
the CLR as simply being a different CPU.

-cd
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top