Overview
Features
Download
Documentation
Community
Add-Ons & Services

Understanding the classloader

Please post support and help requests here.

Understanding the classloader

Postby StrangeMan » 22 Jul 2012, 12:52

Hi!

I've just started to work with the poco library to get a cross-platform plugin system for my application running. I'd like to use the classloader to load classes found in shared libraries. So far, I've managed to compile the lib and get the sample code from the pdf file running:
Code: Select all
   try
   {
      PluginLoader loader;
      std::string libName("GameOfLife");
      libName += Poco::SharedLibrary::suffix(); // append .dll or .so
      loader.loadLibrary(libName);
      { // This is for the iterators to go out of scope so the lib can be unloaded later
         PluginLoader::Iterator it(loader.begin());
         PluginLoader::Iterator end(loader.end());
         for (; it != end; ++it)
         {
            m_logger->logMessage("lib path: " + String(it->first.c_str()));
            PluginManifest::Iterator itMan(it->second->begin());
            PluginManifest::Iterator endMan(it->second->end());
            for (; itMan != endMan; ++itMan)
               m_logger->logMessage("Found " + String(itMan->name()));;
         }
      }
      loader.unloadLibrary(libName);
      m_logger->logMessage("Lib unloaded");
   }
   catch (exception &e)
   {
      m_logger->logMessage("Exception occured while loading plugin libraries: " + String(e.what()));
   }
   catch (...)
   {
      m_logger->logMessage("General Exception occured while loading plugin libraries.");
   }

All of this is placed inside the constructor of one of my main classes. m_logger is a logfile. I guess everything else should be clear.
(Don't be confused with the String stuff. I'm working with JUCE and use most of its classes for my main application).

It loads the lib and finds the class inside it. The problem is, that the application hangs on the unloadLibrary() call. There is no exception! The logfile looks like this:
Code: Select all
**********************************************************
Welcome
Log started: 22 Jul 2012 12:49:01pm

lib path: GameOfLife.dll
Found AppGameOfLife


My main application is a vst-music plugin and I use MS Visual C++ Express under Win7. Therefore I can't attach the debugger to it to see whats going on...

Thanks a lot for hints and tipps.

StrangeMan
StrangeMan
 
Posts: 10
Joined: 22 Jul 2012, 12:40

Re: Understanding the classloader

Postby alex » 22 Jul 2012, 23:10

Is any code executed in the GameOfLife.dll on load ? If so, see what it does.
alex
 
Posts: 1130
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: Understanding the classloader

Postby StrangeMan » 23 Jul 2012, 18:15

The dll file actually contains only a very simple class with just one member function that returns a simple String (its name). There is nothing more that could be executed.

I tried to instantiate this class and call that member function - both works. But then the application hangs when I try to delete the object i instantiated:
Code: Select all
AbstractPlugin* pPluginA = loader.create("PluginA"); // works
m_logger->logMessage(pPluginA.getName()); // works, too
delete pPluginA; // hangs here


I wonder if that happens because I load a dll from inside a dll... (vat-plugins are basically dll files)

StrangeMan
StrangeMan
 
Posts: 10
Joined: 22 Jul 2012, 12:40

Re: Understanding the classloader

Postby alex » 23 Jul 2012, 19:31

I don't know anything about vat-plugins, so won't be of much help there. I think loading dll from another dll is ok as long as you don't end up calling LoadLibrary or FreeLibrary from within another LoadLibrary call (i.e. call Load/FreeLibrary from DllMain):
DLLMain documentation wrote:The entry-point function should perform only simple initialization or termination tasks. It must not call the LoadLibrary or LoadLibraryEx function (or a function that calls these functions), because this may create dependency loops in the DLL load order. This can result in a DLL being used before the system has executed its initialization code. Similarly, the entry-point function must not call the FreeLibrary function (or a function that calls FreeLibrary) during process termination, because this can result in a DLL being used after the system has executed its termination code.
alex
 
Posts: 1130
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: Understanding the classloader

Postby StrangeMan » 24 Jul 2012, 09:30

well, THAT is a useful hint! The code executed inside the constructor of a main class. This constructor might indeed be called inside the initialization process of the vst-plugin (sorry for the typo in the last post) and might therefore be called inside another LoadLibrary call. That would explain, why it all just hangs and never throws an exception. And why the delete operation fails (I never heard, that it could fail for such a simple class).
I'll try to do that stuff outside the normal initialization to avoid that and come back here to post my results.

Is it fine to unload a library inside an unload call? Because that would be a bigger problem!

Thanks for this important hint, alex!
StrangeMan
 
Posts: 10
Joined: 22 Jul 2012, 12:40

Re: Understanding the classloader

Postby StrangeMan » 24 Jul 2012, 09:52

Hi again,

Unfortunately, it didn't help... I placed the code inside a function that is executed on a gui button-press. After clicking the button, it just hangs as it did before. The crash still appears at the same places: the unload library call or, after creating an instance of the desired class: at the delete operation of that instance.

StrangeMan
StrangeMan
 
Posts: 10
Joined: 22 Jul 2012, 12:40

Re: Understanding the classloader

Postby alex » 24 Jul 2012, 13:39

StrangeMan wrote:Is it fine to unload a library inside an unload call? Because that would be a bigger problem!

FreeLibrary documentation wrote:A thread that must unload the DLL in which it is executing and then terminate itself should call FreeLibraryAndExitThread instead of calling FreeLibrary and ExitThread separately. Otherwise, a race condition can occur.
alex
 
Posts: 1130
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: Understanding the classloader

Postby StrangeMan » 07 Aug 2012, 18:54

Hello again!

Does the Poco class loader take care of heap-related problems? I found threads, where people face similar problems that were (in their case) related to the different heap allocators for the dll and the main application.
I guess Poco has already overwritten the delete operator to avoid these problems (seems to be a common solution)?!

StrangeMan

Edit: Nice! When I use loader.destroy("className", pointer); it finally destroys the object. However, it still crashes without exception on the unloadLibrary() call...
StrangeMan
 
Posts: 10
Joined: 22 Jul 2012, 12:40

Re: Understanding the classloader

Postby alex » 07 Aug 2012, 20:56

StrangeMan wrote:I found threads, where people face similar problems that were (in their case) related to the different heap allocators for the dll and the main application.

This happens when you mix modules compiled to different versions (debug/release) or with different compilers (i.e. linked with different runtimes); you allocate on heap, pass pointer across module boundary and try to delete it there (from a different heap). To be safe, don't mix debug/release binaries or the ones compiled with different versions of Visual Studio.
alex
 
Posts: 1130
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: Understanding the classloader

Postby StrangeMan » 07 Aug 2012, 21:50

Hi alex!

See the Edit part of my last post: I managed to get objects deleted by letting the dll do the kob itself. I still can't unload the library though.

StrangeMan
StrangeMan
 
Posts: 10
Joined: 22 Jul 2012, 12:40

Next

Return to Support

Who is online

Users browsing this forum: No registered users and 4 guests

cron