CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6

Thread: Get Public Function in a DLL via VB

  1. #1
    Join Date
    Sep 2002
    Posts
    4

    Question Get Public Function in a DLL via VB

    Hi All,

    How do I know all the Public Functions in a DLL in Visual Basic ?
    Any API to query for these public interfaces ?

    Appreciate any help. Thanks.
    Boon Seong

  2. #2
    Join Date
    Jul 2000
    Location
    Milano, Italy
    Posts
    7,726

    If you can implement IUnknown...

    if you are able to Implement IUnknown (I am not!), it can query interfaces for you ---addendum: seems as if I did not understand myself...Even queryinterface ask you to tell a IID to give you back a pointer to interface, thus it should be more complex...

    From msdn
    How IUnknown Works
    The methods in IUnknown enable an application to query for interfaces on the component and manage the component's reference count. This section contains the following topics.

    Reference Count
    Interface Queries
    Aggregation and Delegation
    Reference Count
    The reference count is an internal variable, incremented in the AddRef method and decremented in the Release method. The base classes manage the reference count and synchronize access to the reference count among multiple threads.

    Interface Queries
    Querying for an interface is also straightforward. The caller passes two parameters: an interface identifier (IID), and the address of a pointer. If the component supports the requested interface, it sets the pointer to the interface, increments its own reference count, and returns S_OK. Otherwise, it sets the pointer to NULL and returns E_NOINTERFACE. The following pseudocode shows the general outline of the QueryInterface method. Component aggregation, described in the next section, introduces some additional complexity.

    if (IID == IID_IUnknown)
    set pointer to (IUnknown *)this
    AddRef
    return S_OK

    else if (IID == IID_ISomeInterface)
    set pointer to (ISomeInterface *)this
    AddRef
    return S_OK

    else if ...

    else
    set pointer to NULL
    return E_NOINTERFACE
    The only difference between the QueryInterface method of one component and the QueryInterface method of another is the list of IIDs that each component tests. For every interface that the component supports, the component must test for the IID of that interface.

    Aggregation and Delegation
    Component aggregation must be transparent to the caller. Therefore, the aggregate must expose a single IUnknown interface, with the aggregated component deferring to the outer component's implementation. Otherwise, the caller would see two different IUnknown interfaces in the same aggregate. If the component is not aggregated, it uses its own implementation.

    To support this behavior, the component must add a level of indirection. A delegating IUnknown delegates the work to the appropriate place: to the outer component, if there is one, or to the component's internal version. A nondelegating IUnknown does the work, as described in the previous section.

    The delegating version is public and keeps the name IUnknown. The nondelegating version is renamed INonDelegatingUnknown. This name is not part of the COM specification, because it is not a public interface.

    When the client creates an instance of the component, it calls the IClassFactory::CreateInstance method. One parameter is a pointer to the aggregating component's IUnknown interface, or is NULL if the new instance is not aggregated. In its constructor method, the component uses this parameter to store a member variable that indicates which IUnknown interface to use, as shown in the following example.

    CMyComponent::CMyComponent(IUnknown *pOuterUnkown)
    {
    if (pOuterUnknown == NULL)
    m_pUnknown = (IUnknown *)(INonDelegatingUnknown *)this;
    else
    m_pUnknown = pOuterUnknown;

    [ ... more constructor code ... ]
    }
    Each method in the delegating IUnknown calls its nondelegating counterpart, as shown in the following example.

    HRESULT QueryInterface(REFIID iid, void **ppv)
    {
    return m_pUnknown->QueryInterface(iid, ppv);
    }
    By the nature of delegation, the delegating methods look identical in every component. Only the nondelegating versions change.

    Using CUnknown
    DirectShow implements IUnknown in a base class called CUnknown. You can use CUnknown to derive other classes, overriding only the methods that change across components. Most of the other base classes in DirectShow derive from CUnknown, so your component can inherit directly from CUnknown or from another base class.

    This section contains the following topics.

    INonDelegatingUnknown

    IUnknown

    Class Constructor

    INonDelegatingUnknown
    CUnknown implements INonDelegatingUnknown. It manages reference counts internally, and in most situations your derived class can inherit the two reference-counting methods with no change. Be aware that CUnknown deletes itself when the reference count drops to zero. On the other hand, you must override NonDelegatingQueryInterface, because the method in the base class returns E_NOINTERFACE if it receives any IID other than IID_IUnknown. In your derived class, test for the IIDs of interfaces that you support, as shown in the following example.

    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv)
    {
    if (riid == IID_ISomeInterface)
    {
    return GetInterface((ISomeInterface*)this, ppv);
    }
    // default
    return CUnknown::NonDelegatingQueryInterface(riid, ppv);
    }
    The utility function GetInterface sets the pointer, increments the reference count in a thread-safe way, and returns S_OK. In the default case, call the base class method and return the result. If you derive from another base class, call its NonDelegatingQueryInterface method instead. This enables you to support all the interfaces that the parent class supports.

    IUnknown
    As mentioned earlier, the delegating version of IUnknown is the same for every component, because it does nothing more than invoke the correct instance of the nondelegating version. For convenience, the header file Combase.h contains a macro, DECLARE_IUNKNOWN, which declares the three delegating methods as inline methods. It expands to the following code.

    STDMETHODIMP QueryInterface(REFIID riid, void **ppv) {
    return GetOwner()->QueryInterface(riid,ppv);
    };
    STDMETHODIMP_(ULONG) AddRef() {
    return GetOwner()->AddRef();
    };
    STDMETHODIMP_(ULONG) Release() {
    return GetOwner()->Release();
    };
    The utility function GetOwner retrieves a pointer to the IUnknown interface of the component that owns this component. For an aggregated component, the owner is the outer component. Otherwise, the component owns itself. Include the DECLARE_IUNKNOWN macro in the public section of your class definition.

    Class Constructor
    Your class constructor should invoke the constructor method for the parent class, in addition to anything it does that is specific to your class. The following example is a typical constructor method.

    CMyComponent(TCHAR *tszName, LPUNKNOWN pUnk, HRESULT *phr)
    : CUnknown(tszName, pUnk, phr)
    {
    /* Other initializations */
    };
    The method takes the following parameters, which it passes directly to the CUnknown constructor method.

    tszName specifies a name for the component.
    pUnk is a pointer to the aggregating IUnknown.
    pHr is a pointer to an HRESULT value, indicating the success or failure of the method.
    Summary
    The following example shows a derived class that supports IUnknown and a hypothetical interface named ISomeInterface.

    class CMyComponent : public CUnknown, public ISomeInterface
    {
    public:

    DECLARE_IUNKNOWN;

    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv)
    {
    if( riid == IID_ISomeInterface )
    {
    return GetInterface((ISomeInterface*)this, ppv);
    }
    return CUnknown::NonDelegatingQueryInterface(riid, ppv);
    }

    CMyComponent(TCHAR *tszName, LPUNKNOWN pUnk, HRESULT *phr)
    : CUnknown(tszName, pUnk, phr)
    {
    /* Other initializations */
    };

    // More declarations will be added later.
    };
    This example illustrates the following points.

    The CUnknown class implements the IUnknown interface. The new component inherits from CUnknown and from any interfaces that the component supports. The component could derive instead from another base class that inherits from CUnknown.
    The DECLARE_IUNKNOWN macro declares the delegating IUnknown methods as inline methods.
    The CUnknown class provides the implementation for INonDelegatingUnknown.
    To support an interface other than IUnknown, the derived class must override the NonDelegatingQueryInterface method and test for the IID of the new interface.
    The class constructor invokes the constructor method for CUnknown.
    The next step in writing a filter is to enable an application to create new instances of the component. This requires an understanding of DLLs and their relation to class factories and class constructor methods. For more information, see How to Create a DLL.

    Last edited by Cimperiali; June 26th, 2003 at 06:54 AM.
    ...at present time, using mainly Net 4.0, Vs 2010



    Special thanks to Lothar "the Great" Haensler, Chris Eastwood , dr_Michael, ClearCode, Iouri and
    all the other wonderful people who made and make Codeguru a great place.
    Come back soon, you Gurus.

  3. #3
    Join Date
    Apr 2002
    Posts
    388
    I also don't understand this thing.
    But as I understand it is only for COM Objects (implementation of IUnknown and so on). So you are not able to get the Interfaces of all DLLs!
    mfg Ungi

    Music, music and VB. VB is like music: You never know how it is interpreted.

  4. #4
    Join Date
    Jul 2000
    Location
    Milano, Italy
    Posts
    7,726

    To tell the truth

    ...If I need to get interfaces, I try with X-ray (a software that try to give you interfaces). But it will not explain more than a journey on the web (to Microsoft.com or the developer of dll). Never needed to retrieve them inside a program at runtime...
    ...at present time, using mainly Net 4.0, Vs 2010



    Special thanks to Lothar "the Great" Haensler, Chris Eastwood , dr_Michael, ClearCode, Iouri and
    all the other wonderful people who made and make Codeguru a great place.
    Come back soon, you Gurus.

  5. #5
    Join Date
    Apr 2002
    Posts
    388
    But there must be a possibility to get the interface of COM-Objects.

    If you have installed the Microsoft Visual Studio there is a tool called OLE/COM Object Viewer. This tool shows you all registered components and the interfaces of them (if there is a typelibery information available).

    I'll try to find out more about this chapter...
    mfg Ungi

    Music, music and VB. VB is like music: You never know how it is interpreted.

  6. #6
    Join Date
    Jul 2000
    Location
    Milano, Italy
    Posts
    7,726

    if typelib is registered...

    ...you could find infos in the registry...
    ...at present time, using mainly Net 4.0, Vs 2010



    Special thanks to Lothar "the Great" Haensler, Chris Eastwood , dr_Michael, ClearCode, Iouri and
    all the other wonderful people who made and make Codeguru a great place.
    Come back soon, you Gurus.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)