Re: Right way of passing unmanaged structures between managed and native code?

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance

From: Ronald Laeremans [MSFT] (ronaldl_at_online.microsoft.com)
Date: 04/01/04


Date: Thu, 1 Apr 2004 09:35:37 -0800

Because the opaqueness means that the compiler generated code uses offsets
directly instead of using any members by name (since there are non). That is
exactly what the native code does.

As an example.

Compiling the following sample.

>>>>>>>>>>>>>>
#using <mscorlib.dll>

struct Foo
{
 int i;
 int j;
};

int main()
{
 Foo foo;
 foo.i = 10;
 foo.j = 11;
   return 0;
}
<<<<<<<<<<<<<<

Leads to the following definition of Foo (from ildasm)

.class public sequential ansi sealed Foo
       extends [mscorlib]System.ValueType
{
  .pack 1
  .size 8
} // end of class Foo

And the following code in main:
(my comments added)

.method public static int32
modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl)
        main() cil managed
{
  .vtentry 1 : 1
  // Code size 16 (0x10)
  .maxstack 2
  .locals init ([0] valuetype Foo foo)
  IL_0000: ldloca.s foo // load the address of local variable foo
  IL_0002: ldc.i4.s 10 // load the constant 10
  IL_0004: stind.i4 // store it there
  IL_0005: ldloca.s foo // load address again
  IL_0007: ldc.i4.4 // add the offset for to get to the address of
foo.j
  IL_0008: add
  IL_0009: ldc.i4.s 11 // what we need to store in it
  IL_000b: stind.i4 // store it
  IL_000c: ldc.i4.0 // 0 return value
  IL_000d: br.s IL_000f // for debugging purposes
  IL_000f: ret
} // end of method 'Global Functions'::main

Ronald

"Vladimir Kouznetsov" <vladimir.kouznetsov@ngrain.com> wrote in message
news:%23xjWoZ4FEHA.3404@TK2MSFTNGP10.phx.gbl...
> Thanks a lot Ronald,
>
> That's a relief! I knew that __value struct may not be binary compatible
> with struct and judging by the context of the article it most probably
> should have been the topic. Though other people could be misled as I was.
Is
> anywhere an explicit statement regarding the matter? That would be nice to
> know it's not going to change in the future.
> BTW why are you saying that opaqueness of the type is the guarantee of
> binary compatibility?
>
> thanks,
> v
>
> "Ronald Laeremans [MSFT]" <ronaldl@online.microsoft.com> wrote in message
> news:%23TGAna3FEHA.2208@TK2MSFTNGP09.phx.gbl...
> > This article is talking about taking (in C++.Net version 7.x terms about
> the
> > layout between:
> >
> > __gc struct Foo
> > {
> > SomeType SomeMember;
> > ...
> > };
> >
> > or
> >
> > __value struct Foo
> > {
> > SomeType SomeMember;
> > };
> >
> > And
> >
> > struct Foo
> > {
> > SomeType SomeMember;
> > }
> >
> > And NOT about the latter definition compiled either with or without the
> > /CLR switch.
> >
> > If you use ildasm on the latter type you will see that it is eximitted
in
> a
> > CLR sense as an opqaue (i.e. empty type) with explicit layout and
explicit
> > size with the compiler generated code directly managing the layout.
Which
> is
> > indeed guaranteed to be the same in either case.
> >
> > Ronald
> >
> > "Vladimir Kouznetsov" <vladimir.kouznetsov@ngrain.com> wrote in message
> > news:OhyZgA2FEHA.3640@tk2msftngp13.phx.gbl...
> > > Thank you Ronald,
> > >
> > > I found the following phrase
> > >
> >
>
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstecha
> > > rt/html/vbtchtroubleshootingnetinteroperability.asp "Troubleshooting
> .NET
> > > Interoperability"): "Because Visual Studio .NET optimizes the way data
> is
> > > stored, the unmanaged representation of the structure does not always
> > match
> > > the managed representation". From that I concluded that either
alignment
> > or
> > > order of members or both can be different for managed and unmanaged
> code.
> > If
> > > I'm misinterpreting that, that probably should be clarified. Otherwise
> if
> > > that is incorrect I'm happy to know that.
> > >
> > > thanks,
> > > v
> > >
> > > "Ronald Laeremans [MSFT]" <ronaldl@online.microsoft.com> wrote in
> message
> > > news:eFothx1FEHA.3064@tk2msftngp13.phx.gbl...
> > > > Hi Vladimir,
> > > >
> > > > Unmanaged types are guaranteed to have the same representation
> > regardless
> > > of
> > > > whether they are compiled with or without the /clr switch. What
> > > > documentation or experiment makes you believe otherwise?
> > > >
> > > > Ronald Laeremans
> > > > Visual C++ team
> > > >
> > > > "Vladimir Kouznetsov" <vladimir.kouznetsov@ngrain.com> wrote in
> message
> > > > news:%23hbHnueFEHA.3032@TK2MSFTNGP09.phx.gbl...
> > > > > Hi group,
> > > > >
> > > > > It seems there are no guarantees that the same unmanaged
structures
> > have
> > > > the
> > > > > same binary representation for managed and native code. How do I
use
> > > them
> > > > in
> > > > > mixed-code assemblies? Is there just some compiler magic behind
> > curtains
> > > > > (IJW, some implicit marshalling, which can lead to a performance
> > > > > degradation) or the data are binary compatible in these scenarios
or
> I
> > > > > perhaps should use attributes to explicitly specify the layout
> (which
> > > BTW
> > > > > may depend on compiler switches increasing complexity of
> maintenance)?
> > > > >
> > > > > thanks,
> > > > > v
> > > > >
> > > > >
> > > >
> > > >
> > >
> > >
> >
> >
>
>



Relevant Pages

  • Re: a case for multiple inheritance
    ... and overrides the write functions to change ... the compiler would optimize it so that the double function call would be ... private new void Foo ... The cast not much ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: a case for multiple inheritance
    ... the compiler would optimize it so that the double function call would be ... private new void Foo ... The cast not much ... This means that if method A1 overrides ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: a case for multiple inheritance
    ... and overrides the write functions to change ... the compiler would optimize it so that the double function call would be ... private new void Foo ... The cast not much ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Operation can be dispatching in only one type
    ... to say that uninitialized is what the programmer wants. ... Some fancy means to tell the compiler that this variable ... So Java speculates that the default constructor is somewhat ... Yes, this is legal, because Foo is called with X having been ...
    (comp.lang.ada)
  • Re: Sacla loop: a new loop implementation
    ... >> Finally, once the foo macro receives its argument, then based on what ... >> depending on how the macro is defined. ... transformations and optimizations deep in the bowels of the compiler, ... > available at macroexpansion time. ...
    (comp.lang.lisp)