Re: ref parameter
- From: parez <psawant@xxxxxxxxx>
- Date: Fri, 6 Jun 2008 12:01:14 -0700 (PDT)
On Jun 6, 1:45 pm, "Peter Duniho" <NpOeStPe...@xxxxxxxxxxxxxxxx>
wrote:
On Fri, 06 Jun 2008 10:09:32 -0700, parez <psaw...@xxxxxxxxx> wrote:
[...]
When you did it the wrong way, you passed it the address of the byte
on the stack. Now, I'm going to *guess* that the stack looked
something like:
[value of TagType]
[value of SerialNo]
[address of param]
(because param is passed in by reference)
The DLL then merrily writes over SerialNo *and then part of 'address
of param'*. Not a problem so far, but...
Why would the dll overwrite the address of param? Just curious..
Let's make sure we understand what is meant by "param" first. :)
Technically, "param" is the local argument to the method. The "address"
of that is simply an offset relative to the current stack frame. But I
don't think that's what's meant in the text quoted.
Rather, in that context, "param" refers to the original parameter, which
is passed as an address stored in a location that is referenced as an
offset relative to the current stack frame. Here, the phrase "address of
param" refers not to the actual address of the local argument relative to
the current stack frame, but rather to the value stored in that location,
the address of the original parameter..
Confused yet? :)
What happens is that when the DLL is called, the OP incorrectly passed the
address of a single byte of storage, rather than an array of bytes of
storage. Furthermore, that single byte was stored on the stack as a local
variable, rather than in the heap. So, when the called function went to
write data to what it thought was an array of bytes, it was actually
writing to that local variable.
But the address of the original parameter passed as "param" was stored in
the stack just past that local variable. Since the local variable didn't
use enough of the stack to accomodate all of the data that the called
function tried to write to it, the address of "param" winds up getting
overwritten as well.
Ironically, the code could have failed in much more spectacular ways. The
OP is fortunate to have had such a clearly incorrect result, but one which
was still testable. :)
Pete
(Bonus reading: of course, the "single byte" variable actually takes up
more room on the stack than just the one byte. I haven't checked, but
probably it's consuming a full 4 bytes, due to alignment requirements.
But that's still not enough for the called function, which apparently was
expecting 7 bytes [why 7? I don't know...that's a weird size for a
buffer]. So three more bytes get written into the "address of param"
storage...just one byte would have been enough to cause the later
assignment to fail, and so it does).
That makes sense. I thought the original problem was somthing else.
v=0
Test(ref v)
// v = 2, as expected
Test2(ref v)
// v = 1. There is no exception thrown
that makes sense.. I thought it was uninitialised ref variable vs
initialised ref. Silly of me. that shouldnt compile..
.
- References:
- ref parameter
- From: Mathijs
- Re: ref parameter
- From: Jon Skeet [C# MVP]
- Re: ref parameter
- From: Mathijs
- Re: ref parameter
- From: Jon Skeet [C# MVP]
- Re: ref parameter
- From: Mathijs
- Re: ref parameter
- From: Jon Skeet [C# MVP]
- Re: ref parameter
- From: parez
- Re: ref parameter
- From: Peter Duniho
- ref parameter
- Prev by Date: VS2008 - How to compile 32bit C# app on Vista64?
- Next by Date: about abstract class and override
- Previous by thread: Re: ref parameter
- Next by thread: Re: ref parameter
- Index(es):
Relevant Pages
|