C++ Question

xtknight

Elite Member
Oct 15, 2004
12,974
0
71
When should I call AddRef of a COM object? Can someone give me all the scenarios? The real problem is, whenever I pass a pointer to an object in a parameter (that was created by QueryInterface or otherwise), the pointer turns to zero by the time the function reads that parameter. Also, if the function tries to change the object, the object is just gone by the time the function is done and I'm back in my original routine. So now I end up with one huge function, since any subroutines can't return the object correctly for some reason. I suspect I need to call AddRef() somewhere.

P.S. Sorry for all the edits, and if you never read my 2nd post about another problem, just ignore that.
 

jboschen

Junior Member
May 18, 2001
18
0
0
g_pControl->AddRef();
hr = g_pGraph->QueryInterface(IID_IMediaControl, (void **)&g_pControl);

This is very wrong. The QueryInterface() method is overwriting the value of g_pControl, which is why you're probably losing ref-counts. You should think of a ref-counted pointer as a unique reference to an object. If you overwrite the reference, the previous value is lost. So if you want to reuse g_pControl, you should be doing this...

g_pControl->Release();
g_pControl = NULL;
hr = g_pGraph->QueryInterface(IID_IMediaControl, (void **)&g_pControl);

 

xtknight

Elite Member
Oct 15, 2004
12,974
0
71
(My original question still remains)

About my other problem: Alright, turns out everything was failing intermittently, not just the subroutine. It was some problem with DirectShow I guess.
 

xtknight

Elite Member
Oct 15, 2004
12,974
0
71
Originally posted by: jboschen
g_pControl->AddRef();
hr = g_pGraph->QueryInterface(IID_IMediaControl, (void **)&g_pControl);

This is very wrong. The QueryInterface() method is overwriting the value of g_pControl, which is why you're probably losing ref-counts. You should think of a ref-counted pointer as a unique reference to an object. If you overwrite the reference, the previous value is lost. So if you want to reuse g_pControl, you should be doing this...

g_pControl->Release();
g_pControl = NULL;
hr = g_pGraph->QueryInterface(IID_IMediaControl, (void **)&g_pControl);

Alright, well g_pControl is NULL to start with and that's the first function I call involving it. So it should just be as follows, right?

hr = g_pGraph->QueryInterface(IID_IMediaControl, (void **)&g_pControl);

Unfortunately, the "unique pointer" stuff means little to me. I'm a newbie, used to coding in Visual Basic. It's my understanding that the following are equivalent.

VB:
dim x as OBJECT
set x = New OBJECT

C++:
OBJECT x;
x->AddRef();

For VB, the object is destroyed when it's out of its scope. For C++, you need to call x->Release(); Does this sound about right? Perhaps I need reference counts explained to me. I actually have no idea what they are.
 

jboschen

Junior Member
May 18, 2001
18
0
0
Alright, well g_pControl is NULL to start with and that's the first function I call involving it. So it should just be as follows, right?

hr = g_pGraph->QueryInterface(IID_IMediaControl, (void **)&g_pControl);

Correct. The call to QueryInterface() will AddRef() g_pControl for you. So now when you no longer need it, you call g_pControl->Release(). AddRef() and Release() must be paired, so it gets confusing as to who calls which at which time. Basically though, output parameters are always AddRef()'d for you by the method you call. Input parameters are expected to be AddRef()'d by you so that the method called can use the parameter during its implicit lifetime without error. If the method you call wants to save it for further work, it will AddRef() and Release() it on it's own. All you need to be sure of is that during the lifetime of the call you KNOW you're making, the parameter is AddRef()'d. After that you can Release() it, keep it around and Release() it later, or whatever. There are subtle variations to these rules when you get into cross-apartment calls, outbound events, etc, but the main rules are as I have said.

As for VB similaries, I haven't used VB in years, but I'm pretty sure this is close to accurate...

' This is somewhere else... VB is hiding the fact that FilgraphManager is a class object
Dim g_Graph As FilgraphManager
Set g_Graph = New FilgraphManager

' Then you have...
Dim g_Control As MediaControl
Set g_Control = g_Graph

To accomplish the same thing in C++, you have this...

// Create a new instance of the FilterGraph (FilgraphManager) class, and request an initial reference to its IGraphBuilder interface
IGraphBuilder* g_pGraph = NULL;
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&g_pGraph);

// Now ask the same instance for a reference to its IMediaControl interface...
IMediaControl* g_pControl = NULL;
g_pGraph->QueryInterface(IID_IMediaControl, (void**)&g_pGraph);

In VB you use New to create objects. In COM, you can use several different methods, but the primary one is CoCreateInstanceEx.

In VB you use Set to convert from one COM interface to another. In COM, you use QueryInterface.

You picked a complicated set of technologies to get your feet wet with C++. COM is tough, DirectShow is also tough, DirectShow in C++ via COM is near torture.

- Jeremy
 

xtknight

Elite Member
Oct 15, 2004
12,974
0
71
OK. It's all starting to make sense now. I've used C and DirectShow enough, but C++ and dealing with objects is another story. I made this program in VB with ease, then I'm porting it to C++. In C++, I have gotten to the point where I can start my app and it will let me watch TV (limited to however the capture filter is currently configured). It did take me roughly five hours though. It's not like I code in C++ every day so I can't say I'm surprised. Anyway back to the point: it turns out my problem wasn't AddRef() at all. The TV capture filter was just acting weird. Stopping my graph at the end of the application fixed that problem.

Thanks for the insight.
 
sale-70-410-exam    | Exam-200-125-pdf    | we-sale-70-410-exam    | hot-sale-70-410-exam    | Latest-exam-700-603-Dumps    | Dumps-98-363-exams-date    | Certs-200-125-date    | Dumps-300-075-exams-date    | hot-sale-book-C8010-726-book    | Hot-Sale-200-310-Exam    | Exam-Description-200-310-dumps?    | hot-sale-book-200-125-book    | Latest-Updated-300-209-Exam    | Dumps-210-260-exams-date    | Download-200-125-Exam-PDF    | Exam-Description-300-101-dumps    | Certs-300-101-date    | Hot-Sale-300-075-Exam    | Latest-exam-200-125-Dumps    | Exam-Description-200-125-dumps    | Latest-Updated-300-075-Exam    | hot-sale-book-210-260-book    | Dumps-200-901-exams-date    | Certs-200-901-date    | Latest-exam-1Z0-062-Dumps    | Hot-Sale-1Z0-062-Exam    | Certs-CSSLP-date    | 100%-Pass-70-383-Exams    | Latest-JN0-360-real-exam-questions    | 100%-Pass-4A0-100-Real-Exam-Questions    | Dumps-300-135-exams-date    | Passed-200-105-Tech-Exams    | Latest-Updated-200-310-Exam    | Download-300-070-Exam-PDF    | Hot-Sale-JN0-360-Exam    | 100%-Pass-JN0-360-Exams    | 100%-Pass-JN0-360-Real-Exam-Questions    | Dumps-JN0-360-exams-date    | Exam-Description-1Z0-876-dumps    | Latest-exam-1Z0-876-Dumps    | Dumps-HPE0-Y53-exams-date    | 2017-Latest-HPE0-Y53-Exam    | 100%-Pass-HPE0-Y53-Real-Exam-Questions    | Pass-4A0-100-Exam    | Latest-4A0-100-Questions    | Dumps-98-365-exams-date    | 2017-Latest-98-365-Exam    | 100%-Pass-VCS-254-Exams    | 2017-Latest-VCS-273-Exam    | Dumps-200-355-exams-date    | 2017-Latest-300-320-Exam    | Pass-300-101-Exam    | 100%-Pass-300-115-Exams    |
http://www.portvapes.co.uk/    | http://www.portvapes.co.uk/    |