www.digitalmars.com         C & C++   DMDScript  

c++.stlsoft - [COMSTL; Adi's report] interface_cast + interface pointers

reply "Matthew" <matthew hat.stlsoft.dot.org> writes:
 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
next sibling parent Adi Shavit <adish gentech.co.il> writes:
<!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&lt;&gt;() 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, &amp;pstm);

  IStream_ptr  p(pstm, false);

  IUnknown_ptr punk = comstl2::interface_cast&lt;IUnknown&gt;(p);

  IMalloc_ptr  pstm2 = comstl2::interface_cast&lt;IMalloc&gt;(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
prev sibling parent reply Adi Shavit <adish gentech.co.il> writes:
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
parent reply "Matthew Wilson" <matthew hat.stlsoft.dot.org> writes:
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
parent reply Adi Shavit <adish gentech.co.il> writes:
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
parent reply "Matthew Wilson" <matthew hat.stlsoft.dot.org> writes:
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
parent reply Adi Shavit <adish gentech.co.il> writes:
<!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">&gt; </span>expect an address of a pointer as
the second argument. This means that
<span class="moz-txt-citetags">&gt; </span>when used with interface_ptr, a
temporary bare pointer must be used to
<span class="moz-txt-citetags">&gt; </span>be given like so:
<span class="moz-txt-citetags">&gt;</span>
<span class="moz-txt-citetags">&gt; </span>       // Create a source filter
specified by filename
<span class="moz-txt-citetags">&gt; </span>      
interface_ptr&lt;IBaseFilter&gt; pSource; // The interface_ptr&lt;&gt; object
<span class="moz-txt-citetags">&gt; </span>       {
<span class="moz-txt-citetags">&gt; </span>          IBaseFilter* ppSource=
NULL; // temporary bare pointer
<span class="moz-txt-citetags"></span><span class="moz-txt-citetags">&gt;</span>
<span class="moz-txt-citetags">&gt; </span>         
if(FAILED(pGraph-&gt;AddSourceFilter(a2w(c_str_ptr(filename)),0,&amp;ppSource)))
<span class="moz-txt-citetags">&gt; </span>          {
<span class="moz-txt-citetags">&gt; </span>             //...
<span class="moz-txt-citetags">&gt; </span>             return 0;
<span class="moz-txt-citetags">&gt; </span>          }
<span class="moz-txt-citetags">&gt; </span>          pSource.set(ppSource,
false); // setting the smart pointer.
<span class="moz-txt-citetags">&gt; </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&lt;IBaseFilter&gt;
pSource; // The interface_ptr&lt;&gt; object
<span class="moz-txt-citetags"></span><span class="moz-txt-citetags"></span>   
    if(FAILED(pGraph-&gt;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>&nbsp;</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>&nbsp;</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" &lt;<a
href="mailto:adish gentech.co.il">adish gentech.co.il</a>&gt;
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&lt;IGraphBuilder&gt; pGraph;<br>
stlsoft::ref_ptr&lt;IMediaControl&gt; pMediaControl;<br>
      </tt><tt>//...<br>
      <br>
      </tt><tt>1.
pMediaControl.set(interface_cast_addref&lt;IMediaControl*&gt;(<b>pGraph.get()</b>),
false); // this is OK<br>
2. </tt><tt>pMediaControl.set(interface_cast_addref&lt;IMediaControl*&gt;(<b>pGraph</b>),
false);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // this blows up.<br>
3. </tt><tt>pMediaControl =
interface_cast&lt;IMediaControl&gt;(<b>pGraph</b>);&nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; // this is OK<br>
      </tt></blockquote>
    <font face="Verdana">Thanks,<br>
Adi<br>
    <br>
    </font><br>
  </blockquote>
</blockquote>
</body>
</html>
Mar 25 2007
parent reply Adi Shavit <adish gentech.co.il> writes:
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
parent reply "Matthew Wilson" <matthew hat.stlsoft.dot.org> writes:
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
next sibling parent Adi Shavit <adish gentech.co.il> writes:
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit


 Still 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
prev sibling parent reply Adi Shavit <adish gentech.co.il> writes:
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
parent reply Adi Shavit <adish gentech.co.il> writes:
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
parent "Matthew Wilson" <matthew hat.stlsoft.dot.org> writes:
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