1

I'm writing a C++ plugin DLL for a 3rd-party Windows application. My plugin DLL can live anywhere on the file system and I specify where it is when loading it from the 3rd-party app.

Part of the functionality of my DLL requires me to use a 3rd party library (ZeroMQ). I linked my DLL to the ZeroMQ library and it built correctly. However, upon loading my DLL in the 3rd party app I kept getting a The specified module could not be found. error. Initially it wasn't clear to me if I used the ZeroMQ static lib if I needed the zeromq DLL as well or not (but apparently it's common to have a static lib that wraps access to the DLL: Using .dll in Visual Studio 2010 C++).

I tried putting the zero mq dll (libzmq-v100-mt-gd-3_2_2.dll in my case) in the same folder as my plugin DLL, however this did not work.

Finally by sheer experimentation I found I could put the zeromq dll directly in the same folder as the main 3rd-party application and now my plugin works. However, ideally I'd rather not do that. Is there a way for me to somehow put the zeromq dll library in the same folder as my plugin DLL? And if so, how? Perhaps some configuration option in Visual Studio when building my DLL?

Community
  • 1
  • 1
User
  • 62,498
  • 72
  • 186
  • 247

3 Answers3

2

What you want to do is delay the DLL loading until later using something like this:

http://msdn.microsoft.com/en-us/library/151kt790.aspx

Delay Loading DLLs

http://www.codeproject.com/Articles/9428/Delay-Loading-a-DLL

Prevent .lib from loading DLL at runtime

Then before the loading happens, dynamically load the DLL using LoadLibrary where you are allowed to enter the entire path of the dll.

When the delay load happens, it will realize that the DLL has already been loaded by your LoadLibrary call, and viola...

Alternatively, instead of loading with LoadLibrary, you can also add your directory to the dll search path using:

http://msdn.microsoft.com/en-us/library/ms686203.aspx

When the delay load happens, it will then look in that directory for the dll, and viola...

Community
  • 1
  • 1
thang
  • 3,466
  • 1
  • 19
  • 31
2

The problem is that the search path that Windows uses when locating dlls includes the path of the application, but not the path of your plugin dll (unless you can convince the application supplier to add this functionality!). When loading your plugin dll the loader sees that it requires functions exported from libzmq-v100-mt-gd-3_2_2.dll, and tried to locate it. What you've found is as expected - the application directory is in the dll search path, so if you place libzmq-v100-mt-gd-3_2_2.dll there the loader will find it correctly, and continue loading your plugin dll. There are ways of adding the path of your plugin to the search path, but unfortunately these can't be used in your dll, as your code will only run if the dll is loaded correctly - which it won't if libzmq-v100-mt-gd-3_2_2.dll isn't found!

Delay loading, as has been suggested, could fix the problem. The other options I can see are:

  • In your plugin installer add the path of your plugin to the PATH environment variable, and put the libzmq-v100-mt-gd-3_2_2.dll at the same location - this method pollutes the PATH variable, and is likely to be fragile
  • Use dynamic linking rather than statically linking to the libzmq-v100-mt-gd-3_2_2.dll your plugin requires - then you have direct control over where you load the dll from using LoadLibrary. The other advantages of this method is that if you fail to find the library your plugin requires you could potentially still activate the plugin but with reduced functionality, or at least supply a meaningful error/log message.
Michael
  • 1,136
  • 1
  • 7
  • 15
0

I recently addressed this exact problem in a blog post: http://otb.manusoft.com/2013/01/using-delayload-to-specify-dependent-dll-path.htm

Owen Wengerd
  • 1,628
  • 1
  • 11
  • 11