[Solved] How to get the list of functions in a dll -Unit testing



  • Hi I am working on a plugin example and trying to open a .dll file. The .dll file contains some methods, I need to display these methods/functions as nodes in a treeView. So how can i get the list of methods/function from a .dll file.



  • That depends on the platform and compiler you are using.
    As you are talking of dlls, I assume you are on windows.

    Which compiler do you use?
    Do you look for C-exported methods?
    You have to read the dll export table and show that, but there is no Qt way for that.



  • On the Windows platform Dependency Walker is your friend:
    http://www.dependencywalker.com/

    But why do you need to list the exports of your plug-in DLL in your program at all?

    Wouldn't it be much easier (and more robust/portable) to make something like a "myApp_initPlugin" function with a fixed name that each plug-in DLL is required to export?

    That function, which is known beforehand, would then be called by the application to "load" the individual plug-in. It would "register" the plug-in to the application, announcing what functions the plug-in does provide...

    (All plug-in API's I am aware of, including Qt's own Plug-in system, work in that way)



  • Hi,

    Thanks for your time and suggestions :)

    @Gerolf
    I am working on windows platform and using MSVC 2010 compiler.

    @MuldeR
    I have a requirement where i need to test my libraries, so I am developing an application like "NUnit":http://www.google.ae/imgres?q=nUnit&um=1&hl=en&sa=N&biw=1486&bih=753&tbm=isch&tbnid=TIXxxfMFrlbhEM:&imgrefurl=http://www.dotnetjohn.com/articles.aspx?articleid=146&docid=4U1gLAxG0dFd9M&imgurl=http://www.dotnetjohn.com/Images/nunit2.JPG&w=756&h=512&ei=HCu7T4C7FcyWhQf04bH-CA&zoom=1&iact=hc&vpx=1057&vpy=365&dur=304&hovh=185&hovw=273&tx=108&ty=63&sig=113437160135027356483&page=2&tbnh=121&tbnw=179&start=28&ndsp=35&ved=1t:429,r:12,s:28,i:156 interface (for unit testing) where i use some plugin logic to create my dlls of my test classes and through the application/GUI we can load the dll file that displays the test functions in a tableView/treeView.

    So now i am trying the same architecture proposed by you where each class will register itself to an interface/class and from the application i should be able to load the classes and its test functions.

    So i need some idea about how to implement this. I got some information "here":http://qtcreator.blogspot.com/2009/10/running-multiple-unit-tests.html where the test classes register's itself.

    Thanks for you time :)



  • Make a class like this whose only instance will live in the "main" application:

    @class CPluginRegistry
    {
    /* ... */

    public:
    registerPlugin(CPluginBaseClass *plugin);

    protected:
    QMap<QString, CPluginBaseClass*> m_plugins;
    }

    void CPluginRegistry::registerPlugin(CPluginBaseClass plugin)
    {
    QString pluginName = plugin->getName();
    plugin->getPluginCapabilities(); /
    application-specific, be creative here !!! */
    m_plugins.insert(pluginName, plugin);
    }@

    The function that each plug-in DLL is required to export could look like:

    @//The plug-in class
    class CSomeConcretePluginClass : public CPluginBaseClass
    {
    /* all plug-in specific code goes here! */
    }

    //Public plug-in API
    extern "C"
    {
    __decsplec(dllexport) void initPluginDLL(CPluginRegistry *registry)
    {
    CPluginBaseClass *myPlugin = new CSomeConcretePluginClass();
    registry -> registerPlugin(myPlugin);
    }
    }@

    The Code in the main app would look like this:
    @CPluginRegistry g_registry = NULL;
    QList<QLibraray
    > *g_libraries = NULL;

    typedef void (*PluginInitFunc)(CPluginRegistry *registry);

    void loadAllPlugins(void)
    {
    if(!g_registry) g_registry = new CPluginRegistry();
    if(!g_libraries) g_libraries = new QList<QLibraray*>;

    for(/* each .dll file in the "plugins" directory */)
    {
        PluginInitFunc funcPtr = NULL;
        QLibraray *currentPlugin = new QLibraray(path_to_dll);
        
        if(funcPtr = (PluginInitFunc) currentPlugin->resolve("initPluginDLL"))
        {
            funcPtr(g_registry); //Call plugin "init" function to let plugin register itself!
            g_libraries << currentPlugin; //remember pointer for later clean-up!
        }
        else
        {
            delete currentPlugin; //Something went wrong :-(
        }
    }
    

    }@



  • Hi MulderR,
    Thanks for the code. I'll have to try it and check.

    As of now i am trying to register the test classes as provided "here":http://qtcreator.blogspot.com/2009/10/running-multiple-unit-tests.html

    I have an interface

    @class PluginInterface
    {
    public:
    virtual QList<QObject*> LiTestList();
    };

    Q_DECLARE_INTERFACE(PluginInterface,"com.testing.PluginInterface 0.0.1")@

    and another class that subclasses this interface class

    @namespace AutoTest
    {

    typedef QList<QObject*> TestList;
    
    inline TestList& testList()
    {
        static TestList list;
        return list;
    }
    
    inline bool findObject(QObject* object)
    {
        TestList& list = testList();
        if (list.contains(object))
        {
            return true;
        }
        foreach (QObject* test, list)
        {
            if (test->objectName() == object->objectName())
            {
                return true;
            }
        }
        return false;
    }
    
    
    inline void addTest(QObject* object)
    {
        TestList& list = testList();
        if (!findObject(object))
        {
            list.append(object);
        }
    }
    

    }

    template <class T>

    class Test : public PluginInterface
    {
    Q_INTERFACES(PluginInterface)
    public:
    QList<QObject*> LiTestList()
    {
    return AutoTest::testList();
    }

    QSharedPointer<T> child;
    Test(const QString& name) : child(new T)
    {
        child->setObjectName(name);
        AutoTest::addTest(child.data());
    }
    

    };

    Q_EXPORT_PLUGIN2(UnitTestingPlugin,Test) <-- This gives error!!!!!!!

    #define DECLARE_TEST(className) static Test<className> t(#className);@

    I want to create a .dll file so i use Q_EXPORT_PLUGIN2 macro, but this gives me the following error

    @Error:
    c:\testing\unittestingplugin\AutoTest.h:70: error: C2955: 'Test' : use of class template requires template argument list

    c:\testing\unittestingplugin\AutoTest.h:70: error: C2512: 'Test' : no appropriate default constructor available

    c:\testing\unittestingplugin\AutoTest.h:70: error: C2955: 'Test' : use of class template requires template argument list@

    Please suggest what changes should i make.



  • Finally I got my code working with a different approach. I created a wrapper class that subclasses my interface and all my testClasses register's to the AutoTest. Also the interface class provided the list of testClasses.

    Thanks for your time :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.