0

Is there an alternative to using the following?

class IGraphBuilder;

public ref class Device
{
private:
    IGraphBuilder* pGraphBuilder;

public:
    void Configure()
    {
        pin_ptr<IGraphBuilder*> ppGraphBuilder = &pGraphBuilder;

        HRESULT hr = CoCreateInstance(CLSID_FilterGraph,
            NULL,
            CLSCTX_INPROC,
            IID_IGraphBuilder, (void**)ppGraphBuilder);

reinterpret_cast(ppGraphBuilder) compiles but I'm a bit confused if this is correct for this case.

If this wasn't C++/CLI (where &NativeMember actually means interior_ptr<Type>(NativeMember)) I would simply use static_cast<void**>(&pGraphBuilder) but even after correctly casting to pin_ptr the following doesn't compile

pin_ptr<IGraphBuilder*> ppGraphBuilder = &pGraphBuilder;
static_cast<void**>(ppGraphBuilder)

Is there any solution or am I forced to use (void**) because pin_ptr is weird?

NtscCobalt
  • 1,639
  • 2
  • 15
  • 31

1 Answers1

1

reinterpret_cast (and thus C cast) is potentially not ok, although it may work due to the allegedly trivial layout of pin_ptr. Indeed you have to call the conversion operator from cli::pin_ptr<IGraphBuilder*> to IGraphBuilder** first (hence the complain from the compiler).

reinterpret_cast<void**>(static_cast<IGraphBuilder**>(ppGraphBuilder))

is correct. You may want to introduce a intermediary variable of type IGraphBuilder** first:

pin_ptr<IGraphBuilder*> p = &pGraphBuilder;
IGraphBuilder** ppGraphBuilder = p;

HRESULT hr = CoCreateInstance(CLSID_FilterGraph,
        NULL,
        CLSCTX_INPROC,
        IID_IGraphBuilder, reinterpret_cast<void**>(p));
Alexandre C.
  • 55,948
  • 11
  • 128
  • 197
  • Doing that errors in `C2440: 'static_cast' : cannot convert from 'IGraphBuilder **' to 'void **'` This thread talks about the same issue... http://stackoverflow.com/questions/3625410/c-static-cast-from-float-to-void/ – NtscCobalt Apr 24 '12 at 21:57
  • @NtscCobalt: You're right. One has to use `reinterpret_cast` for the second cast. This does not change the fact that technically, you need two conversions. – Alexandre C. Apr 25 '12 at 07:28
  • is `reinterpret_cast` in that case safe to use after first casting to `IGraphBuilder**`? – NtscCobalt Apr 25 '12 at 21:34
  • @NtscCobalt: Yes, otherwise you would never be able to do COM. – Alexandre C. Apr 26 '12 at 07:22
  • @Alaxandre C. ah ok thank you. Casting using the C style `(void**)` does work and is currently in place `(void**)pin_ptr(&pGraphBuilder)`. I will change all of my C++/CLI COM calls to look like your post now for readability and safety. Thanks. – NtscCobalt Apr 26 '12 at 18:24