c++.stlsoft - [COMSTL; Adi's report] interface_cast + interface pointers
- "Matthew" <matthew hat.stlsoft.dot.org> Dec 02 2006
- Adi Shavit <adish gentech.co.il> Dec 05 2006
- Adi Shavit <adish gentech.co.il> Mar 21 2007
- "Matthew Wilson" <matthew hat.stlsoft.dot.org> Mar 21 2007
- Adi Shavit <adish gentech.co.il> Mar 22 2007
- "Matthew Wilson" <matthew hat.stlsoft.dot.org> Mar 22 2007
- Adi Shavit <adish gentech.co.il> Mar 25 2007
- Adi Shavit <adish gentech.co.il> Apr 08 2007
- "Matthew Wilson" <matthew hat.stlsoft.dot.org> Apr 08 2007
- Adi Shavit <adish gentech.co.il> Apr 08 2007
- Adi Shavit <adish gentech.co.il> Apr 15 2007
- Adi Shavit <adish gentech.co.il> Apr 28 2007
- "Matthew Wilson" <matthew hat.stlsoft.dot.org> Apr 28 2007
6. Allow interface_cast_addref<>() to accept interface_ptr arguments instead of just bare pointers. This would allow more readable code.
This is something that I actually achieved a couple of years ago, and never got round to releasing. (I'd planned to discuss this as part of a series on smart pointers for the Smart Pointers column, but that dragged its feet, and ...) As it stands, it supports code such as the following: { LPSTREAM pstm; HRESULT hr = ::CreateStreamOnHGlobal(NULL, true, &pstm); IStream_ptr p(pstm, false); IUnknown_ptr punk = comstl2::interface_cast<IUnknown>(p); IMalloc_ptr pstm2 = comstl2::interface_cast<IMalloc>(punk); } I think you'll agree that this is rather good stuff. I will make it a priority to have this in 1.9.1. Cheers Matthew
Dec 02 2006
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000099">
<font face="Verdana">Yes, that's exactly what I had in mind.<br>
Adi<br>
<br>
</font><br>
Matthew wrote:
<blockquote cite="midekt5r6$2064$1 digitaldaemon.com" type="cite">
<blockquote type="cite">
<pre wrap="">6. Allow interface_cast_addref<>() to accept
interface_ptr arguments
instead of just bare pointers.
This would allow more readable code.
</pre>
</blockquote>
<pre wrap=""><!---->
This is something that I actually achieved a couple of years ago, and never
got round to releasing. (I'd planned to discuss this as part of a series on
smart pointers for the Smart Pointers column, but that dragged its feet, and
...)
As it stands, it supports code such as the following:
{
LPSTREAM pstm;
HRESULT hr = ::CreateStreamOnHGlobal(NULL, true, &pstm);
IStream_ptr p(pstm, false);
IUnknown_ptr punk = comstl2::interface_cast<IUnknown>(p);
IMalloc_ptr pstm2 = comstl2::interface_cast<IMalloc>(punk);
}
I think you'll agree that this is rather good stuff. I will make it a
priority to have this in 1.9.1.
Cheers
Matthew
</pre>
</blockquote>
</body>
</html>
Dec 05 2006
Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi Matt, I'm reviving an old thread... Matthew wrote:6. Allow interface_cast_addref<>() to accept interface_ptr arguments instead of just bare pointers. This would allow more readable code.
This is something that I actually achieved a couple of years ago, and never got round to releasing. (I'd planned to discuss this as part of a series on smart pointers for the Smart Pointers column, but that dragged its feet, and ...) As it stands, it supports code such as the following: { LPSTREAM pstm; HRESULT hr = ::CreateStreamOnHGlobal(NULL, true, &pstm); IStream_ptr p(pstm, false); IUnknown_ptr punk = comstl2::interface_cast<IUnknown>(p); IMalloc_ptr pstm2 = comstl2::interface_cast<IMalloc>(punk); } I think you'll agree that this is rather good stuff. I will make it a priority to have this in 1.9.1.
I'm having problems using this. Here's my /working /code: //... stlsoft::ref_ptr<IGraphBuilder> pGraph; stlsoft::ref_ptr<IMediaControl> pMediaControl; //... if(SUCCEEDED(co_create_instance(CLSID_FilterGraph, *pGraph*))) { pMediaControl.set(interface_cast_addref<IMediaControl*>(*pGraph.get()*), false); //... When I remove the *.get()* the whole thing blows up: pMediaControl.set(interface_cast_addref<IMediaControl*>(*pGraph*), false); The compilation errors are really weird: --------------------Configuration: ConsoleApp - Win32 Debug-------------------- Compiling... SequenceProcessor.cpp h:\adish\dev\stlsoft\include\comstl\conversion\interface_cast.hpp(351) : error C2784: 'I *__cdecl stlsoft::comstl_project::simple_interface_cast(I *)' : could not deduce template argument for ' *' from 'class stlsoft::ref_ptr<struct IGraphBuilder,st ruct IGraphBuilder,struct IGraphBuilder>' h:\adish\dev\stlsoft\include\comstl\conversion\interface_cast.hpp(566) : see reference to function template instantiation '__thiscall stlsoft::comstl_project::interface_cast_base<struct IMediaControl *,struct stlsoft::comstl_project::addref_ release<struct IMediaControl *>,struct stlsoft::comstl_project::ignore_interface_cast_exception>::stlsoft::comstl_project::interface_cast_base<struct IMediaControl *,struct stlsoft::comstl_project::addref_release<struct IMediaControl *>,struct stlso ft::comstl_project::ignore_interface_cast_exception>(class stlsoft::ref_ptr<struct IGraphBuilder,struct IGraphBuilder,struct IGraphBuilder> &,enum stlsoft::comstl_project::interface_cast_base<struct IMediaControl *,struct stlsoft::comstl_project::ad dref_release<struct IMediaControl *>,struct stlsoft::comstl_project::ignore_interface_cast_exception>::NullThrowPermission)' being compiled h:\adish\dev\stlsoft\include\comstl\conversion\interface_cast.hpp(353) : fatal error C1903: unable to recover from previous error(s); stopping compilation h:\adish\dev\stlsoft\include\comstl\conversion\interface_cast.hpp(566) : see reference to function template instantiation '__thiscall stlsoft::comstl_project::interface_cast_base<struct IMediaControl *,struct stlsoft::comstl_project::addref_ release<struct IMediaControl *>,struct stlsoft::comstl_project::ignore_interface_cast_exception>::stlsoft::comstl_project::interface_cast_base<struct IMediaControl *,struct stlsoft::comstl_project::addref_release<struct IMediaControl *>,struct stlso ft::comstl_project::ignore_interface_cast_exception>(class stlsoft::ref_ptr<struct IGraphBuilder,struct IGraphBuilder,struct IGraphBuilder> &,enum stlsoft::comstl_project::interface_cast_base<struct IMediaControl *,struct stlsoft::comstl_project::ad dref_release<struct IMediaControl *>,struct stlsoft::comstl_project::ignore_interface_cast_exception>::NullThrowPermission)' being compiled Error executing cl.exe. I suspect it has something to do with MSVC6. Any thought? Thanks, Adi
Mar 21 2007
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
As far as I can remember, the adjustment to interface_cast_addref<> to =
take ref_ptr<X> arguments has _not_ been done, so the code as you've =
written it will not work.
However, the following (cleaner, nicer, more transparent) version =
should:
//...
stlsoft::ref_ptr<IGraphBuilder> pGraph;
stlsoft::ref_ptr<IMediaControl> pMediaControl;
//...
if(SUCCEEDED(co_create_instance(CLSID_FilterGraph, pGraph)))
{
pMediaControl =3D interface_cast<IMediaControl>(pGraph);
//...
:-)
Matt
"Adi Shavit" <adish gentech.co.il> wrote in message =
news:ets930$28it$1 digitalmars.com...
Hi Matt,
I'm reviving an old thread...=20
Matthew wrote:=20
6. Allow interface_cast_addref<>() to accept interface_ptr arguments
instead of just bare pointers.
This would allow more readable code.
=20
This is something that I actually achieved a couple of years ago, and =
never
got round to releasing. (I'd planned to discuss this as part of a series =
on
smart pointers for the Smart Pointers column, but that dragged its feet, =
and
...)
As it stands, it supports code such as the following:
{
LPSTREAM pstm;
HRESULT hr =3D ::CreateStreamOnHGlobal(NULL, true, &pstm);
IStream_ptr p(pstm, false);
IUnknown_ptr punk =3D comstl2::interface_cast<IUnknown>(p);
IMalloc_ptr pstm2 =3D comstl2::interface_cast<IMalloc>(punk);
}
I think you'll agree that this is rather good stuff. I will make it a
priority to have this in 1.9.1.
Has this actually been done?
I'm having problems using this.=20
Here's my working code:
//...
stlsoft::ref_ptr<IGraphBuilder> pGraph;
stlsoft::ref_ptr<IMediaControl> pMediaControl;
//...
if(SUCCEEDED(co_create_instance(CLSID_FilterGraph, pGraph)))
{
=
pMediaControl.set(interface_cast_addref<IMediaControl*>(pGraph.get()), =
false);
//...
When I remove the .get() the whole thing blows up:
=
pMediaControl.set(interface_cast_addref<IMediaControl*>(pGraph), false);
The compilation errors are really weird:
--------------------Configuration: ConsoleApp - Win32 =
Debug--------------------
Compiling...
SequenceProcessor.cpp
=
h:\adish\dev\stlsoft\include\comstl\conversion\interface_cast.hpp(351) : =
error C2784: 'I *__cdecl =
stlsoft::comstl_project::simple_interface_cast(I *)' : could not deduce =
template argument for ' *' from 'class stlsoft::ref_ptr<struct =
IGraphBuilder,st
ruct IGraphBuilder,struct IGraphBuilder>'
=
h:\adish\dev\stlsoft\include\comstl\conversion\interface_cast.hpp(566) : =
see reference to function template instantiation '__thiscall =
stlsoft::comstl_project::interface_cast_base<struct IMediaControl =
*,struct stlsoft::comstl_project::addref_
release<struct IMediaControl *>,struct =
stlsoft::comstl_project::ignore_interface_cast_exception>::stlsoft::comst=
l_project::interface_cast_base<struct IMediaControl *,struct =
stlsoft::comstl_project::addref_release<struct IMediaControl *>,struct =
stlso
ft::comstl_project::ignore_interface_cast_exception>(class =
stlsoft::ref_ptr<struct IGraphBuilder,struct IGraphBuilder,struct =
IGraphBuilder> &,enum =
stlsoft::comstl_project::interface_cast_base<struct IMediaControl =
*,struct stlsoft::comstl_project::ad
dref_release<struct IMediaControl *>,struct =
stlsoft::comstl_project::ignore_interface_cast_exception>::NullThrowPermi=
ssion)' being compiled
=
h:\adish\dev\stlsoft\include\comstl\conversion\interface_cast.hpp(353) : =
fatal error C1903: unable to recover from previous error(s); stopping =
compilation
=
h:\adish\dev\stlsoft\include\comstl\conversion\interface_cast.hpp(566) : =
see reference to function template instantiation '__thiscall =
stlsoft::comstl_project::interface_cast_base<struct IMediaControl =
*,struct stlsoft::comstl_project::addref_
release<struct IMediaControl *>,struct =
stlsoft::comstl_project::ignore_interface_cast_exception>::stlsoft::comst=
l_project::interface_cast_base<struct IMediaControl *,struct =
stlsoft::comstl_project::addref_release<struct IMediaControl *>,struct =
stlso
ft::comstl_project::ignore_interface_cast_exception>(class =
stlsoft::ref_ptr<struct IGraphBuilder,struct IGraphBuilder,struct =
IGraphBuilder> &,enum =
stlsoft::comstl_project::interface_cast_base<struct IMediaControl =
*,struct stlsoft::comstl_project::ad
dref_release<struct IMediaControl *>,struct =
stlsoft::comstl_project::ignore_interface_cast_exception>::NullThrowPermi=
ssion)' being compiled
Error executing cl.exe.
I suspect it has something to do with MSVC6.
Any thought?
Thanks,
Adi
Mar 21 2007
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Indeed, it does!
Can you explain what the difference is between each of the versions, and
why this (confusing) redundancy exists?
Here they are for reference:
//...
stlsoft::ref_ptr<IGraphBuilder> pGraph;
stlsoft::ref_ptr<IMediaControl> pMediaControl;
//...
1.
pMediaControl.set(interface_cast_addref<IMediaControl*>(*pGraph.get()*),
false); // this is OK
2.
pMediaControl.set(interface_cast_addref<IMediaControl*>(*pGraph*),
false); // this blows up.
3. pMediaControl = interface_cast<IMediaControl>(*pGraph*);
// this is OK
Thanks,
Adi
Matthew Wilson wrote:
As far as I can remember, the adjustment to interface_cast_addref<> to
take ref_ptr<X> arguments has _not_ been done, so the code as you've
written it will not work.
However, the following (cleaner, nicer, more transparent) version should:
//...
stlsoft::ref_ptr<IGraphBuilder> pGraph;
stlsoft::ref_ptr<IMediaControl> pMediaControl;
//...
if(SUCCEEDED(co_create_instance(CLSID_FilterGraph, *pGraph*)))
{
pMediaControl = interface_cast<IMediaControl>(*pGraph*);
//...
:-)
Matt
Mar 22 2007
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
1. is a cast from a pointer to a pointre
3. is a case from a smartptr to a smartptr
2. is an error (I presume when you say blows up you mean it fails to =
compile?)
I don't know what you mean by "confusing redundancy". I don't see any =
redundancy at all, since it is no more/less reasonable to want to be =
able to cast raw pointers as smartptrs. Is that what you mean?
"Adi Shavit" <adish gentech.co.il> wrote in message =
news:eturnn$6cq$1 digitalmars.com...
Indeed, it does!
Can you explain what the difference is between each of the versions, =
and why this (confusing) redundancy exists?
Here they are for reference:
//...
stlsoft::ref_ptr<IGraphBuilder> pGraph;
stlsoft::ref_ptr<IMediaControl> pMediaControl;
//...
1. =
pMediaControl.set(interface_cast_addref<IMediaControl*>(pGraph.get()), =
false); // this is OK
2. pMediaControl.set(interface_cast_addref<IMediaControl*>(pGraph), =
false); // this blows up.
3. pMediaControl =3D interface_cast<IMediaControl>(pGraph); =
// this is OK
Thanks,
Adi
Matthew Wilson wrote:=20
As far as I can remember, the adjustment to interface_cast_addref<> =
to take ref_ptr<X> arguments has _not_ been done, so the code as you've =
written it will not work.
However, the following (cleaner, nicer, more transparent) version =
should:
//...
stlsoft::ref_ptr<IGraphBuilder> pGraph;
stlsoft::ref_ptr<IMediaControl> pMediaControl;
//...
if(SUCCEEDED(co_create_instance(CLSID_FilterGraph, pGraph)))
{
pMediaControl =3D interface_cast<IMediaControl>(pGraph);
//...
:-)
Matt
Mar 22 2007
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
<title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
<font face="Verdana">Yes, of course, you're right.<br>
I got a bit disoriented due to the similar names and the template
types, thus the "confusing" bit.<br>
I re-read your article <i><b>"enhanced comstl::interface_cast"</b></i>
and that sorted me out.<br>
<br>
Anyway, I have a bigger challenge. One that I don't think has a simple
solution.<br>
ref_ptr + interface_cast give a very robust and readable interface to
COM programming. That's great.<br>
However, there are still some places where I wish a cleaner syntax was
possible.<br>
<br>
Here's a quote from my original question list:<br>
<br>
</font>
<blockquote>
<pre wrap="">5. Functions like co_create_instance and other initialization
functions
<span class="moz-txt-citetags">> </span>expect an address of a pointer as
the second argument. This means that
<span class="moz-txt-citetags">> </span>when used with interface_ptr, a
temporary bare pointer must be used to
<span class="moz-txt-citetags">> </span>be given like so:
<span class="moz-txt-citetags">></span>
<span class="moz-txt-citetags">> </span> // Create a source filter
specified by filename
<span class="moz-txt-citetags">> </span>
interface_ptr<IBaseFilter> pSource; // The interface_ptr<> object
<span class="moz-txt-citetags">> </span> {
<span class="moz-txt-citetags">> </span> IBaseFilter* ppSource=
NULL; // temporary bare pointer
<span class="moz-txt-citetags"></span><span class="moz-txt-citetags">></span>
<span class="moz-txt-citetags">> </span>
if(FAILED(pGraph->AddSourceFilter(a2w(c_str_ptr(filename)),0,&ppSource)))
<span class="moz-txt-citetags">> </span> {
<span class="moz-txt-citetags">> </span> //...
<span class="moz-txt-citetags">> </span> return 0;
<span class="moz-txt-citetags">> </span> }
<span class="moz-txt-citetags">> </span> pSource.set(ppSource,
false); // setting the smart pointer.
<span class="moz-txt-citetags">> </span> }
</pre>
<pre wrap=""><!---->[your wrote:] Agree that this is not pretty.</pre>
</blockquote>
<font face="Verdana">Indeed, it is not pretty. This type of code
appears in several places in my program.<br>
Since <b>pSource </b>is initially empty, it does not even have a raw
ptr to pass to <b>AddSourceFilter</b>().<br>
<br>
I was wondering if there might be a way to make this prettier.<br>
It would be nice to have something like this:<br>
<br>
</font>
<blockquote>
<pre wrap=""><span class="moz-txt-citetags"> </span> // Create a source
filter specified by filename
<span class="moz-txt-citetags"> </span> interface_ptr<IBaseFilter>
pSource; // The interface_ptr<> object
<span class="moz-txt-citetags"></span><span class="moz-txt-citetags"></span>
if(FAILED(pGraph->AddSourceFilter(a2w(c_str_ptr(filename)),0,
<b>pSource.getAssignableInterface(false)</b>)))
<span class="moz-txt-citetags"></span> {
<span class="moz-txt-citetags"></span> //...
<span class="moz-txt-citetags"></span> return 0;
<span class="moz-txt-citetags"></span> }
<span class="moz-txt-citetags"></span></pre>
</blockquote>
<font face="Verdana">Where, presumably, <b>getAssignableInterface()</b>
returns an <b>IBaseFilter**</b> instance or something convertable to
it (the false regards the ref-count).<br>
<br>
I don't really have a concrete idea about how this might be
implemented, though maybe if a temporary </font><font
face="Verdana"><b>IBaseFilter**
</b></font><font face="Verdana">convertable object is returned, then
checks/updates to the actual <b>pSource </b>could be done in the
temp's dtor. Also, this convertable class could be made temp only, or
something along these lines...<br>
<br>
Any thoughts?<br>
<br>
Adi<br>
<br>
<br>
</font><br>
Matthew Wilson wrote:
<blockquote cite="midetv7es$les$1 digitalmars.com" type="cite">
<title></title>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
<meta content="MSHTML 6.00.2800.1589" name="GENERATOR">
<div><font face="Arial" size="2">1. is a cast from a pointer to a
pointre</font></div>
<div><font face="Arial" size="2">3. is a case from a smartptr to a
smartptr</font></div>
<div><font face="Arial" size="2">2. is an error (I presume when you
say blows up you mean it fails to compile?)</font></div>
<div> </div>
<div><font face="Arial" size="2">I don't know what you mean by
"confusing redundancy". I don't see any redundancy at all, since it is
no more/less reasonable to want to be able to cast raw pointers as
smartptrs. Is that what you mean?</font></div>
<div> </div>
<blockquote dir="ltr"
style="border-left: 2px solid rgb(0, 0, 0); padding-right: 0px; padding-left:
5px; margin-left: 5px; margin-right: 0px;">
<div>"Adi Shavit" <<a
href="mailto:adish gentech.co.il">adish gentech.co.il</a>>
wrote in message <a href="news:eturnn$6cq$1 digitalmars.com">news:eturnn$6cq$1 digitalmars.com</a>...</div>
<font face="Verdana">Indeed, it does!<br>
<br>
Can you explain what the difference is between each of the versions,
and why this (confusing) redundancy exists?<br>
<br>
Here they are for reference:<br>
</font>
<blockquote><tt>//...<br>
stlsoft::ref_ptr<IGraphBuilder> pGraph;<br>
stlsoft::ref_ptr<IMediaControl> pMediaControl;<br>
</tt><tt>//...<br>
<br>
</tt><tt>1.
pMediaControl.set(interface_cast_addref<IMediaControl*>(<b>pGraph.get()</b>),
false); // this is OK<br>
2. </tt><tt>pMediaControl.set(interface_cast_addref<IMediaControl*>(<b>pGraph</b>),
false); // this blows up.<br>
3. </tt><tt>pMediaControl =
interface_cast<IMediaControl>(<b>pGraph</b>);
// this is OK<br>
</tt></blockquote>
<font face="Verdana">Thanks,<br>
Adi<br>
<br>
</font><br>
</blockquote>
</blockquote>
</body>
</html>
Mar 25 2007
Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Any comments on this? Adi Adi Shavit wrote:Yes, of course, you're right. I got a bit disoriented due to the similar names and the template types, thus the "confusing" bit. I re-read your article /*"enhanced comstl::interface_cast"*/ and that sorted me out. Anyway, I have a bigger challenge. One that I don't think has a simple solution. ref_ptr + interface_cast give a very robust and readable interface to COM programming. That's great. However, there are still some places where I wish a cleaner syntax was possible. Here's a quote from my original question list: 5. Functions like co_create_instance and other initialization functions > expect an address of a pointer as the second argument. This means that > when used with interface_ptr, a temporary bare pointer must be used to > be given like so: > > // Create a source filter specified by filename > interface_ptr<IBaseFilter> pSource; // The interface_ptr<> object > { > IBaseFilter* ppSource= NULL; // temporary bare pointer > > if(FAILED(pGraph->AddSourceFilter(a2w(c_str_ptr(filename)),0,&ppSource))) > { > //... > return 0; > } > pSource.set(ppSource, false); // setting the smart pointer. > } [your wrote:] Agree that this is not pretty. Indeed, it is not pretty. This type of code appears in several places in my program. Since *pSource *is initially empty, it does not even have a raw ptr to pass to *AddSourceFilter*(). I was wondering if there might be a way to make this prettier. It would be nice to have something like this: // Create a source filter specified by filename interface_ptr<IBaseFilter> pSource; // The interface_ptr<> object if(FAILED(pGraph->AddSourceFilter(a2w(c_str_ptr(filename)),0, *pSource.getAssignableInterface(false)*))) { //... return 0; } Where, presumably, *getAssignableInterface()* returns an *IBaseFilter*** instance or something convertable to it (the false regards the ref-count). I don't really have a concrete idea about how this might be implemented, though maybe if a temporary *IBaseFilter** *convertable object is returned, then checks/updates to the actual *pSource *could be done in the temp's dtor. Also, this convertable class could be made temp only, or something along these lines... Any thoughts? Adi Matthew Wilson wrote:1. is a cast from a pointer to a pointre 3. is a case from a smartptr to a smartptr 2. is an error (I presume when you say blows up you mean it fails to compile?) I don't know what you mean by "confusing redundancy". I don't see any redundancy at all, since it is no more/less reasonable to want to be able to cast raw pointers as smartptrs. Is that what you mean? "Adi Shavit" <adish gentech.co.il <mailto:adish gentech.co.il>> wrote in message news:eturnn$6cq$1 digitalmars.com... Indeed, it does! Can you explain what the difference is between each of the versions, and why this (confusing) redundancy exists? Here they are for reference: //... stlsoft::ref_ptr<IGraphBuilder> pGraph; stlsoft::ref_ptr<IMediaControl> pMediaControl; //... 1. pMediaControl.set(interface_cast_addref<IMediaControl*>(*pGraph.get()*), false); // this is OK 2. pMediaControl.set(interface_cast_addref<IMediaControl*>(*pGraph*), false); // this blows up. 3. pMediaControl = interface_cast<IMediaControl>(*pGraph*); // this is OK Thanks, Adi
Apr 08 2007
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Still thinking.
You know me - sometimes months or years pass before I get an answer on =
an ng question. :-)
I had an idea yesterday actually, but haven't had time to even write it =
down yet.
Matthew
P.S. Any response to my be.speech idea? ;-)
"Adi Shavit" <adish gentech.co.il> wrote in message =
news:evbhs3$2r39$1 digitalmars.com...
Any comments on this?
Adi
Adi Shavit wrote:=20
Yes, of course, you're right.
I got a bit disoriented due to the similar names and the template =
types, thus the "confusing" bit.
I re-read your article "enhanced comstl::interface_cast" and that =
sorted me out.
Anyway, I have a bigger challenge. One that I don't think has a =
simple solution.
ref_ptr + interface_cast give a very robust and readable interface =
to COM programming. That's great.
However, there are still some places where I wish a cleaner syntax =
was possible.
Here's a quote from my original question list:
5. Functions like co_create_instance and other initialization functions
expect an address of a pointer as the second argument. This means that
when used with interface_ptr, a temporary bare pointer must be used to
be given like so:
// Create a source filter specified by filename
interface_ptr<IBaseFilter> pSource; // The interface_ptr<> =
{
IBaseFilter* ppSource=3D NULL; // temporary bare pointer
=
{
//...
return 0;
}
pSource.set(ppSource, false); // setting the smart pointer.
}
This type of code appears in several places in my program.
Since pSource is initially empty, it does not even have a raw ptr to =
pass to AddSourceFilter().
I was wondering if there might be a way to make this prettier.
It would be nice to have something like this:
// Create a source filter specified by filename
interface_ptr<IBaseFilter> pSource; // The interface_ptr<> =
object
if(FAILED(pGraph->AddSourceFilter(a2w(c_str_ptr(filename)),0, =
pSource.getAssignableInterface(false))))
{
//...
return 0;
}
Where, presumably, getAssignableInterface() returns an IBaseFilter** =
instance or something convertable to it (the false regards the =
ref-count).
I don't really have a concrete idea about how this might be =
implemented, though maybe if a temporary IBaseFilter** convertable =
object is returned, then checks/updates to the actual pSource could be =
done in the temp's dtor. Also, this convertable class could be made temp =
only, or something along these lines...
Any thoughts?
Adi
Matthew Wilson wrote:=20
1. is a cast from a pointer to a pointre
3. is a case from a smartptr to a smartptr
2. is an error (I presume when you say blows up you mean it fails =
to compile?)
I don't know what you mean by "confusing redundancy". I don't see =
any redundancy at all, since it is no more/less reasonable to want to be =
able to cast raw pointers as smartptrs. Is that what you mean?
"Adi Shavit" <adish gentech.co.il> wrote in message =
news:eturnn$6cq$1 digitalmars.com...
Indeed, it does!
Can you explain what the difference is between each of the =
versions, and why this (confusing) redundancy exists?
Here they are for reference:
//...
stlsoft::ref_ptr<IGraphBuilder> pGraph;
stlsoft::ref_ptr<IMediaControl> pMediaControl;
//...
1. =
pMediaControl.set(interface_cast_addref<IMediaControl*>(pGraph.get()), =
false); // this is OK
2. =
pMediaControl.set(interface_cast_addref<IMediaControl*>(pGraph), false); =
// this blows up.
3. pMediaControl =3D interface_cast<IMediaControl>(pGraph); =
// this is OK
Thanks,
Adi
Apr 08 2007
Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bitStill thinking. You know me - sometimes months or years pass before I get an answer on an ng question. :-)
I think what I had in mind is similar to your invoke_get<> idea,P.S. Any response to my be.speech idea? ;-)
I'll resend in case it didn't come thorough. Adi
Apr 08 2007
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Hi,
I wrote a little proof-of-concept shim for doing this.
It seems to work as expected, while preventing naive misuse.
template <class T>
class raw_assignment_shim
{
*public:*
operator T::resource_type*() // conversion op
{ return &res_; }
~raw_assignment_shim() // dtor
{
// do some checks here...
ref_.set(res_, false);
}
*private:*
friend raw_assignment_shim<T> make_raw_assignment_shim(T& ref);
raw_assignment_shim(T& ref): // private ctor
res_(ref.get()),
ref_(ref)
{}
T::resource_type operator*(); // not implemented. Prevents de-ref.
*private:*
T::resource_type res_;
T& ref_;
};
template <class T>
raw_assignment_shim<T> make_raw_assignment_shim(T& ref)
{ return raw_assignment_shim<T>(ref); }
///////////////////////////////////////////////////////////////////////////////////
bool SequenceProcessor::createFilterGraph(string filename)
{
using winstl::a2w;
// Create a source filter specified by filename
*ref_ptr<IBaseFilter> pSource;*
if(FAILED(pGraph->AddSourceFilter(a2w(filename),0,
*make_raw_assignment_shim(pSource)*)))
{
::MessageBox( NULL, "Unable to create source filter",
"Error", MB_OK | MB_ICONINFORMATION );
return 0;
}
/* // original code...
// Create a source filter specified by filename
ref_ptr<IBaseFilter> pSource;
{
IBaseFilter* ppSource= NULL;
if(FAILED(pGraph->AddSourceFilter(a2w(filename),0,&ppSource)))
{
::MessageBox( NULL, "Unable to create source filter",
"Error", MB_OK | MB_ICONINFORMATION );
return 0;
}
pSource.set(ppSource, false);
}
*/
...
Of course, the names can be changed, and some refinements should
probably be added.
Such as limit it only for initializing an empty (NULL) ref_ptr<>,
exceptions etc.
What do you think?
Adi
Apr 15 2007
Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Any comments on this? Adi Shavit wrote:Hi, I wrote a little proof-of-concept shim for doing this. It seems to work as expected, while preventing naive misuse. template <class T> class raw_assignment_shim { *public:* operator T::resource_type*() // conversion op { return &res_; } ~raw_assignment_shim() // dtor { // do some checks here... ref_.set(res_, false); } *private:* friend raw_assignment_shim<T> make_raw_assignment_shim(T& ref); raw_assignment_shim(T& ref): // private ctor res_(ref.get()), ref_(ref) {} T::resource_type operator*(); // not implemented. Prevents de-ref. *private:* T::resource_type res_; T& ref_; }; template <class T> raw_assignment_shim<T> make_raw_assignment_shim(T& ref) { return raw_assignment_shim<T>(ref); } /////////////////////////////////////////////////////////////////////////////////// bool SequenceProcessor::createFilterGraph(string filename) { using winstl::a2w; // Create a source filter specified by filename *ref_ptr<IBaseFilter> pSource;* if(FAILED(pGraph->AddSourceFilter(a2w(filename),0, *make_raw_assignment_shim(pSource)*))) { ::MessageBox( NULL, "Unable to create source filter", "Error", MB_OK | MB_ICONINFORMATION ); return 0; } /* // original code... // Create a source filter specified by filename ref_ptr<IBaseFilter> pSource; { IBaseFilter* ppSource= NULL; if(FAILED(pGraph->AddSourceFilter(a2w(filename),0,&ppSource))) { ::MessageBox( NULL, "Unable to create source filter", "Error", MB_OK | MB_ICONINFORMATION ); return 0; } pSource.set(ppSource, false); } */ ... Of course, the names can be changed, and some refinements should probably be added. Such as limit it only for initializing an empty (NULL) ref_ptr<>, exceptions etc. What do you think? Adi
Apr 28 2007
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
There will be.
Am crammed with the very last bits of XSTL - CD, index, final page =
proofs.
After that, things will be more 'Active'. (Get it?!?! <g>)
"Adi Shavit" <adish gentech.co.il> wrote in message =
news:f0vcml$kcd$1 digitalmars.com...
Any comments on this?
Adi Shavit wrote:=20
Hi,
I wrote a little proof-of-concept shim for doing this.
It seems to work as expected, while preventing naive misuse.
template <class T>
class raw_assignment_shim
{
public:
operator T::resource_type*() // conversion op
{ return &res_; }
~raw_assignment_shim() // dtor
{
// do some checks here...
ref_.set(res_, false);
}
private:
=20
friend raw_assignment_shim<T> make_raw_assignment_shim(T& ref);
raw_assignment_shim(T& ref): // private ctor
res_(ref.get()),
ref_(ref)
{}
T::resource_type operator*(); // not implemented. Prevents =
de-ref.
private:
T::resource_type res_;
T& ref_;
};
template <class T>
raw_assignment_shim<T> make_raw_assignment_shim(T& ref)
{ return raw_assignment_shim<T>(ref); }
=
/////////////////////////////////////////////////////////////////////////=
//////////
bool SequenceProcessor::createFilterGraph(string filename)=20
{
using winstl::a2w;
// Create a source filter specified by filename
ref_ptr<IBaseFilter> pSource;
if(FAILED(pGraph->AddSourceFilter(a2w(filename),0, =
make_raw_assignment_shim(pSource))))
{
::MessageBox( NULL, "Unable to create source filter",
"Error", MB_OK | MB_ICONINFORMATION );
return 0;
}
/* // original code...
// Create a source filter specified by filename
ref_ptr<IBaseFilter> pSource;
{
IBaseFilter* ppSource=3D NULL;
=
if(FAILED(pGraph->AddSourceFilter(a2w(filename),0,&ppSource)))
{
::MessageBox( NULL, "Unable to create source filter",
"Error", MB_OK | MB_ICONINFORMATION );
return 0;
}
pSource.set(ppSource, false);
}
*/
...
Of course, the names can be changed, and some refinements should =
probably be added.
Such as limit it only for initializing an empty (NULL) ref_ptr<>, =
exceptions etc.
What do you think?
Adi
Apr 28 2007









Adi Shavit <adish gentech.co.il> 