Thread overview
Extra argument being passed?
Jun 02, 2004
Malcolm Sharpe
Jun 02, 2004
Malcolm Sharpe
Jun 02, 2004
Stephan Wienczny
Jun 02, 2004
Malcolm Sharpe
Jun 04, 2004
Walter
Jun 09, 2004
Malcolm Sharpe
June 02, 2004
I am trying to port a small C++ program using DirectShow to D.  Mostly, it has been working fine.  However, one method call has problems with a null reference being passed, even though there is no argument.  I'll snip out the relevent sections of code (minus some error-checking) to clarify:

// dshow.d

module dshow;

...

interface IMediaEvent : IDispatch
{
extern (Windows):

...

	HRESULT WaitForCompletion(long msTimeout, long * pEvCode);

...

}

...


// test.d

import dshow;

...

IMediaEvent event = null;

...

graph.QueryInterface(&IID_IMediaEvent, cast(void**)(&event));

...

long evCode;
event.WaitForCompletion(INFINITE, &evCode);

...


The program has an access violation on that last line (event.WaitForCompletion).  It turns out it is a null reference problem.  According to the Visual Studio debugger, this is the disassembly for that last line:


00402169  lea         eax,[evCode]
0040216C  push        eax
0040216D  push        0
0040216F  push        0FFFFFFFFh
00402171  push        dword ptr [event]
00402174  mov         ecx,dword ptr [event]
00402177  mov         edx,dword ptr [ecx]
00402179  call        dword ptr [edx+24h]
0040217C  add         esp,20h
0040217F  mov         dword ptr [ebp-4],0
00402186  jmp         +18Ch (40219Ch)


The interesting line is 0040216D.  It seems something is being pushed onto the stack in between INFINITE and &evCode.  I'm still somewhat of a new programmer, so I don't know exactly what's going on here, but I can hazard a guess that the 0 is an argument that is being mistakenly passed to WaitForCompletiion.  If I step to the offending line and then set the execution to the next line (thereby running every line except the offending line) the code works and evCode is assigned a value.

Clearly something's up.  Any ideas?  I can post the full code of the program if I need to, but there are about 1000 lines between both files.

- Malcolm Sharpe
June 02, 2004
I should probably mention the command line I am compiling with:

dmd.exe test.d dshow.d uuid.lib ole32.lib -g -gt -debug
June 02, 2004
See Comments

Malcolm Sharpe wrote:
 >
> 00402169  lea         eax,[evCode]		//Calculates relative address of evCode
> 0040216C  push        eax			//pushes that value onto the stack
> 0040216D  push        0			//pushes 0 on the stack
> 0040216F  push        0FFFFFFFFh		//pushes infinite on the stack
> 00402171  push        dword ptr [event]	//pushes event as dword onto stack
> 00402174  mov         ecx,dword ptr [event]	//moves event into ecx
> 00402177  mov         edx,dword ptr [ecx]	//moves ecx into edx  (=event)
> 00402179  call        dword ptr [edx+24h]	//call into vtable of event
> 0040217C  add         esp,20h			//Add 20 to esp ;-) Whatever is there
> 0040217F  mov         dword ptr [ebp-4],0	//Move something
> 00402186  jmp         +18Ch (40219Ch)		//Jump to 18C after 40218C
> 
> 
> The interesting line is 0040216D.  It seems something is being pushed onto the stack in between INFINITE and &evCode.  I'm still somewhat of a new programmer, so I don't know exactly what's going on here, but I can hazard a guess that the 0 is an argument that is being mistakenly passed to WaitForCompletiion.  If I step to the offending line and then set the execution to the next line (thereby running every line except the offending line) the code works and evCode is assigned a value.
> 
> Clearly something's up.  Any ideas?  I can post the full code of the program if I need to, but there are about 1000 lines between both files.
> 
> - Malcolm Sharpe

I don't know what the 0 is for, too. Maybe my comments make it easier to read for the next one. Maybe this is a compiler bug?
June 02, 2004
Stephan Wienczny wrote:
> See Comments
> 
> Malcolm Sharpe wrote:
>  >
> 
>> 00402169  lea         eax,[evCode]        //Calculates relative address of evCode
>> 0040216C  push        eax            //pushes that value onto the stack
>> 0040216D  push        0            //pushes 0 on the stack
>> 0040216F  push        0FFFFFFFFh        //pushes infinite on the stack
>> 00402171  push        dword ptr [event]    //pushes event as dword onto stack
>> 00402174  mov         ecx,dword ptr [event]    //moves event into ecx
>> 00402177  mov         edx,dword ptr [ecx]    //moves ecx into edx  (=event)
>> 00402179  call        dword ptr [edx+24h]    //call into vtable of event
>> 0040217C  add         esp,20h            //Add 20 to esp ;-) Whatever is there
>> 0040217F  mov         dword ptr [ebp-4],0    //Move something
>> 00402186  jmp         +18Ch (40219Ch)        //Jump to 18C after 40218C
>>
>>
>> The interesting line is 0040216D.  It seems something is being pushed onto the stack in between INFINITE and &evCode.  I'm still somewhat of a new programmer, so I don't know exactly what's going on here, but I can hazard a guess that the 0 is an argument that is being mistakenly passed to WaitForCompletiion.  If I step to the offending line and then set the execution to the next line (thereby running every line except the offending line) the code works and evCode is assigned a value.
>>
>> Clearly something's up.  Any ideas?  I can post the full code of the program if I need to, but there are about 1000 lines between both files.
>>
>> - Malcolm Sharpe
> 
> 
> I don't know what the 0 is for, too. Maybe my comments make it easier to read for the next one. Maybe this is a compiler bug?

That's about what I thought that code did.  The jmp instruction is there because the method call is at the end of a try block.  Maybe the add and mov are there as part of that as well.  Here's some more information that might be helpful: if I replace

long evCode;
event.WaitForCompletion(INFINITE, &evCode);

with

OAEVENT hEvent;
event.GetEventHandle(&hEvent);

the event.GetEventHandle(&hEvent); statement produces the disassembly

0040213D  lea         edx,[hEvent]
00402140  push        edx
00402141  push        dword ptr [event]
00402144  mov         ebx,dword ptr [event]
00402147  mov         esi,dword ptr [ebx]
00402149  call        dword ptr [esi+1Ch]
0040214C  add         esp,1Ch
0040214F  mov         dword ptr [ebp-4],0
00402156  jmp         +15Ch (40216Ch)

and there is no error.  It is also clear that there is no extra argument being passed, unlike in the problem code.
June 04, 2004
The 'extra argument' you see is the hidden 'this' pointer. 'this' points to the instance of the interface object. But you've set 'event' to null.

"Malcolm Sharpe" <masharpe2000@yahoo.ca> wrote in message news:c9j781$2r8t$1@digitaldaemon.com...
> I am trying to port a small C++ program using DirectShow to D.  Mostly, it has been working fine.  However, one method call has problems with a null reference being passed, even though there is no argument.  I'll snip out the relevent sections of code (minus some error-checking) to clarify:
>
> // dshow.d
>
> module dshow;
>
> ...
>
> interface IMediaEvent : IDispatch
> {
> extern (Windows):
>
> ...
>
> HRESULT WaitForCompletion(long msTimeout, long * pEvCode);
>
> ...
>
> }
>
> ...
>
>
> // test.d
>
> import dshow;
>
> ...
>
> IMediaEvent event = null;
>
> ...
>
> graph.QueryInterface(&IID_IMediaEvent, cast(void**)(&event));
>
> ...
>
> long evCode;
> event.WaitForCompletion(INFINITE, &evCode);
>
> ...
>
>
> The program has an access violation on that last line
> (event.WaitForCompletion).  It turns out it is a null reference problem.
>   According to the Visual Studio debugger, this is the disassembly for
> that last line:
>
>
> 00402169  lea         eax,[evCode]
> 0040216C  push        eax
> 0040216D  push        0
> 0040216F  push        0FFFFFFFFh
> 00402171  push        dword ptr [event]
> 00402174  mov         ecx,dword ptr [event]
> 00402177  mov         edx,dword ptr [ecx]
> 00402179  call        dword ptr [edx+24h]
> 0040217C  add         esp,20h
> 0040217F  mov         dword ptr [ebp-4],0
> 00402186  jmp         +18Ch (40219Ch)
>
>
> The interesting line is 0040216D.  It seems something is being pushed onto the stack in between INFINITE and &evCode.  I'm still somewhat of a new programmer, so I don't know exactly what's going on here, but I can hazard a guess that the 0 is an argument that is being mistakenly passed to WaitForCompletiion.  If I step to the offending line and then set the execution to the next line (thereby running every line except the offending line) the code works and evCode is assigned a value.
>
> Clearly something's up.  Any ideas?  I can post the full code of the program if I need to, but there are about 1000 lines between both files.
>
> - Malcolm Sharpe


June 09, 2004
I'm not sure I understand; "push dword ptr [event]" seems to be the hidden 'this' pointer, as far as I can tell.  Are you saying that "push 0" is also a hidden 'this' pointer?  'event' should have a value at that point, because of "graph.QueryInterface(&IID_IMediaEvent, cast(void**)(&event));", so is there some confusion (maybe because I am casting the pointer)?

Walter wrote:
> The 'extra argument' you see is the hidden 'this' pointer. 'this' points to
> the instance of the interface object. But you've set 'event' to null.
> 
> "Malcolm Sharpe" <masharpe2000@yahoo.ca> wrote in message
> news:c9j781$2r8t$1@digitaldaemon.com...
> 
>>I am trying to port a small C++ program using DirectShow to D.  Mostly,
>>it has been working fine.  However, one method call has problems with a
>>null reference being passed, even though there is no argument.  I'll
>>snip out the relevent sections of code (minus some error-checking) to
>>clarify:
>>
>>// dshow.d
>>
>>module dshow;
>>
>>...
>>
>>interface IMediaEvent : IDispatch
>>{
>>extern (Windows):
>>
>>...
>>
>>HRESULT WaitForCompletion(long msTimeout, long * pEvCode);
>>
>>...
>>
>>}
>>
>>...
>>
>>
>>// test.d
>>
>>import dshow;
>>
>>...
>>
>>IMediaEvent event = null;
>>
>>...
>>
>>graph.QueryInterface(&IID_IMediaEvent, cast(void**)(&event));
>>
>>...
>>
>>long evCode;
>>event.WaitForCompletion(INFINITE, &evCode);
>>
>>...
>>
>>
>>The program has an access violation on that last line
>>(event.WaitForCompletion).  It turns out it is a null reference problem.
>>  According to the Visual Studio debugger, this is the disassembly for
>>that last line:
>>
>>
>>00402169  lea         eax,[evCode]
>>0040216C  push        eax
>>0040216D  push        0
>>0040216F  push        0FFFFFFFFh
>>00402171  push        dword ptr [event]
>>00402174  mov         ecx,dword ptr [event]
>>00402177  mov         edx,dword ptr [ecx]
>>00402179  call        dword ptr [edx+24h]
>>0040217C  add         esp,20h
>>0040217F  mov         dword ptr [ebp-4],0
>>00402186  jmp         +18Ch (40219Ch)
>>
>>
>>The interesting line is 0040216D.  It seems something is being pushed
>>onto the stack in between INFINITE and &evCode.  I'm still somewhat of a
>>new programmer, so I don't know exactly what's going on here, but I can
>>hazard a guess that the 0 is an argument that is being mistakenly passed
>>to WaitForCompletiion.  If I step to the offending line and then set the
>>execution to the next line (thereby running every line except the
>>offending line) the code works and evCode is assigned a value.
>>
>>Clearly something's up.  Any ideas?  I can post the full code of the
>>program if I need to, but there are about 1000 lines between both files.
>>
>>- Malcolm Sharpe
> 
> 
>