Help translating Reflector deconstruction into com

2019-07-16 05:36发布

问题:

So I am Reflector-ing some framework 2.0 code and end up with the following deconstruction

fixed (void* voidRef3 = ((void*) &_someMember))
{
...
}

This won't compile due to 'The right hand side of a fixed statement assignment may not be a cast expression'

I understand that Reflector can only approximate and generally I can see a clear path but this is a bit outside my experience.

Question: what is Reflector trying to describe to me?

Update:

Am also seeing the following

fixed (IntPtr* ptrRef3 = ((IntPtr*) &this._someMember))

Update:

So, as Mitch says, it is not a bitwise operator, but an addressOf operator.

Question is now:

fixed (IntPtr* ptrRef3 = &_someMember)

fails with an 'Cannot implicitly convert type 'xxx*' to 'System.IntPtr*'. An explicit conversion exists (are you missing a cast?)' compilation error.

So I seemed to be damned if I do and damned if I dont. Any ideas?

UPDATE:

I think i have it figured. By chance I went back to the expression that was using void* and removed the casts and VS stopped complaining and since I gathered from the participants in this conversation that void* and intptr* are equivalent I simply swapped them out, resulting in this:

fixed (void* ptrRef3 = &_someMember)

and VS stopped complaining. Can someone verify that

fixed (void* ptrRef3 = &_someMember)

is equivalent to

fixed (IntPtr* ptrRef3 = &_someMember)

?

回答1:

It is taking the address of _someMember and casting it to (void *) (i.e. a pointer address), and then setting a location to that address.

The fixed statement 'pins' the object, and prevents the GC from moving it around.

The '&' used in that context is the 'Address Of' operator, not Bitwise And.

In response to updated question:

Have you tried:

fixed (void* voidRef3 = &_someMember) 
{ 
... 
}


回答2:

Responding to your last comment: does this work for you?

fixed (IntPtr* ptrRef3 = (IntPtr *) &_someMember)

Edit

I'm not sure what you mean

that is effectively what reflector gave me

The error you mention seems quite clear: it can explicitly convert from (void *) to (IntPtr *) if you ask. My example asks, yours doesn't.

Are you really getting the same error message when you insert the (IntPtr *)?

Another Edit

Can someone verify that

fixed (void* ptrRef3 = &_someMember)

is equivalent to

fixed (IntPtr* ptrRef3 = &_someMember)

First of all: yes, they're equivalent.

Second of all: I've been thinking about what all this means. I think the decompiler figures it doesn't know enough to create a movable reference to _someMember, and so can't leave it to the C# runtime to manage it. To cope with this, it uses fixed to disable garbage collection for that memory, leaving it to you to tell the runtime when it's safe to deallocate.

Therefore this is not code you should keep around: as soon as you figure out the real meaning and lifespan of that bit of data, rewrite it to use regular (garbage collected) variables.