> I just started trying to upgrade our code to use the asynchronous interface
> and I am a bit perplexed at the mix of C and C++. In other libraries the
> callbacks generally have a void pointer to clientData or ‘instance’ or
> something like that which allows me to pass the ‘this’ pointer, cast it, to
> the class and access all the particular instances’ members. In the openRTSP
> and PlayCommon code I see the signatures for the callbacks are hard coded to
> foo(RTSPClient::responsehandler*,int,char*).
The "openRTSP.cpp"/"playCommon.cpp" code, unfortunately, does not provide the
greatest example of how to use the asynchronous "RTSPClient" interface,
precisely because it uses a single, global "RTSPClient*" variable (called
"ourRTSPClient"). (Also, because "playCommon.cpp" shares code with a separate
application called "playSIP".)
The key thing to note is that the "RTSPClient:responseHandler()" functions all
have a "RTSPClient*" as their first parameter. When the response handler gets
called, its first parameter will be (a pointer to) the "RTSPClient" object that
made the request. In our "playCommon.cpp" code, the first parameter to our
response handler functions ends up not being needed, because its value will -
in this case - be the same as our global variable "ourRTSPClient". In your
case, however, you will want to use this first parameter, because it will tell
you which particular "RTSPClient" object made the request.
> For example. This is what causes the ourRTSPClient in the example to be a
> Global variable. I need to have this as a class member variable, and perhaps
> do something like this….
>
> getOptions(RTSPClient::responseHandler* afterFunc, void* clientData) {
> myClass * instancePTR = (myClass *) clientData;
> instancePTR->ourClient_->sendOptionsCommand(instancePTR,
> ourAuthenticator, clientData);
> }
No, this won't work, because the signature of your call to
"RTSPClient::sendOptionsCommand()" is all wrong.
Instead, don't define or call a "getOptions()" function at all. Instead just
call:
instancePTR->ourClient->sendOptionsCommand(continueAfterOPTIONS,
ourAuthenticator);
And then, when the "continueAfterOPTIONS()" response handler later gets called,
its first parameter will be "instancePTR->ourClient" - i.e., a "RTSPClient*".
If you need more information from this "RTSPClient*" pointer (e.g., in your
case, to identify it's "myClass*" parent), then you can do so by subclassing
"RTSPClient", and putting the information that you want in a subclass member
field.
> What is the best way to use these callbacks in a multi threaded (multiple
> UsageEnvironments) c++ program.?
You do realize, I hope, that the use of the asynchronous "RTSPClient" interface
makes it even less necessary to use multiple threads. (If you use the
asynchronous interface, you can access multiple RTSP streams concurrently from
a single thread (running a single event loop).) But if you insist on using
multiple threads (something that I still don't recommend, even though it's
possible), you can do so provided that you use a separate "TaskScheduler" and
"UsageEnvironment" for each. Note that - if you wish - you can call
"->envir()" on your response handlers' "RTSPClient*" first parameter, if you
need to find out which "UsageEnvironment" - and thus which thread - it is using.
Ross Finlayson
Live Networks, Inc.
http://www.live555.com/
_______________________________________________
live-devel mailing list
[email protected]
http://lists.live555.com/mailman/listinfo/live-devel