How to create a COMInterface having a vtbl pointer?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

How to create a COMInterface having a vtbl pointer?

Maxim Fridental
Hallo,

I have to use one specific DLL function, that gives me back a pointer to an
instance of a COM interface (inherited directly from IUnknown), that is, a
pointer to the virtual table. How can I create an IUnknown (for instance)
using this pointer?
Thanks.

Best Regards
Maxim Fridental


Reply | Threaded
Open this post in threaded view
|

Re: How to create a COMInterface having a vtbl pointer?

Blair McGlashan
"Maxim Fridental" <[hidden email]> wrote in message
news:b3kogn$1n9mi7$[hidden email]...
> Hallo,
>
> I have to use one specific DLL function, that gives me back a pointer to
an
> instance of a COM interface (inherited directly from IUnknown), that is, a
> pointer to the virtual table. How can I create an IUnknown (for instance)
> using this pointer?
> Thanks.

How does it return the interface pointer? If via an output parameter (the
normal COM practice), then follow a similar pattern to
ShellLibrary>>allocator, i.e.

    answer := IMalloc newPointer.
    self SHGetMalloc: answer.

If the function returns a COM interface pointer, i.e. it is declared
something like this:

    getInterface
        <stdcall: IUnknown* GetInterface>

 then you should call it like this:

    answer := MyDLL getInterface.
    answer beFinalizable.

The #beFinalizable is necessary (in D5, though it won't be in D6), because
the VM's external call primitive can correctly construct ExternalStructure
references, but doesn't (in D5) handle COM interface pointers specifically,
and so doesn't know to mark the object as finalizble so that the reference
count can be released when it is GC'd.

In both cases it is assumed that the called function has already increased
the reference count of the interface pointer it has returned (which is the
COM convention). If you have an un-ref. counted raw pointer, you can use
IXXXX>>fromAddress: to convert it into the appropriate interface class, and
add a reference.

Of course once you have an IUnknown, you can use #queryInterface: <class> to
"cast" it to another interface type.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: How to create a COMInterface having a vtbl pointer?

Maxim Fridental
Hello Blair,

thank you for your answer. I have unfortunately an another case. The
function I have to use receives a pointer to a pointer to the COM interface,
that is, IUnknown**. I've found, that the following do the job:
    pInterface := LPVOID new.
    MyLibrary default createInterface: pInterface.
    interface := IUnknown fromAddress: pInterface yourAddress.
I'm hoping it is the proper way to do things...

Best Regards
Maxim Fridental


Reply | Threaded
Open this post in threaded view
|

Re: How to create a COMInterface having a vtbl pointer?

Blair McGlashan
"Maxim Fridental" <[hidden email]> wrote in message
news:b3v82d$1qq7cr$[hidden email]...
> Hello Blair,
>
> thank you for your answer. I have unfortunately an another case. The
> function I have to use receives a pointer to a pointer to the COM
interface,
> that is, IUnknown**. I've found, that the following do the job:
>     pInterface := LPVOID new.
>     MyLibrary default createInterface: pInterface.
>     interface := IUnknown fromAddress: pInterface yourAddress.
> I'm hoping it is the proper way to do things...

Actually this is the normal case i.e. an output parameter which is an
interface pointer, requiring one level of indirection for each. You don't
need the LPVOID intermediary, and also the above will leak an interface
reference count. Assuming that the parameter is declared as void**, then you
should be able to rewrite it as:

    pInterface := IUnknown newPointer.
    MyLibrary default createInterface: pInterface.

Regards

Blair