3

I have an old C++ library which has been designed for use in single-threaded environmens.

The library exposes the interfaces for initialization, which change the internal data structures of the library, and usage, which only reads data and makes calculations.

My objective is to use this library in a Windows multithreaded application, with different threads calling instances of the dll initialized with different data.

Assuming that rewriting the dll to allow multithreading would be prohibitive, is there some way to let multiple instances of a DLL exist in the same process, with separate memory spaces, or to obtain a similar result by other means?

Coffee on Mars
  • 988
  • 6
  • 21
  • Another idea I found, which might be interesting, is to use different AppDomains, creating one with each instance of a library and loading the same into it: AppDomains provide separate memory spaces and can be unloaded, freeing both process memory and loaded assemblies within. – Coffee on Mars Feb 20 '11 at 14:04

2 Answers2

6

If the DLL contains static resources, then those would be shared among all instances created.

One possible way would be to create a single instance and restrict access to it using some kind of lock mechanism. This may reduce performance depending on usage, but without modifying internal structure of DLL, it may be difficult to work with multiple instance.

Shamim Hafiz - MSFT
  • 21,454
  • 43
  • 116
  • 176
  • 5
    I agree with the general idea, but beware that it can still go wrong if the dll is using thread-local storage. Since it's designed single-threaded, it won't be using TLS *on purpose*, but it might be using it indirectly via a dependency. So if you setup from one thread, you might find that calls from another thread don't work. The next level of wrapping is instead of just a lock, create a thread whose sole purpose is to manage this dll, and access all the dll's functions by sending messages to this thread and waiting for responses. – Steve Jessop Feb 17 '11 at 11:27
  • @Steve Jessop: this was my first idea, but in this case I could only initialize the dll with one set of data at a time: the ideal solution would allow to have different initialization parameters for each thread at the same time. – Coffee on Mars Feb 17 '11 at 12:04
  • 2
    @Coffee: ah, sorry, I didn't properly catch that not only does the dll not support multiple threads, it also has global data that in effect you want to be handle-specific. I'm sure you can clone a dll by brute force - rename it and then access it only via LoadLibrary/GetProcAddress, not by linking. That's only really good for a fixed number of copies, though, I'm not sure you want your executable to be choosing a new name for the dll on the fly. Might work as long as the machine isn't locked down, but distinctly hacky. – Steve Jessop Feb 17 '11 at 12:24
  • @Coffee I don't understand why you accepted this answer. It doesn't answer your question. My answer and Steve's comment (which I had not read before I added my answer) are the only option for you. Did I misunderstand your question? Are you in fact content with just a single instance of the DLL? – David Heffernan Feb 17 '11 at 14:44
  • Another way, less or more hacky depending on your tastes, would be to create an executable which handles the dll loading and I/O, and spawn multiple instances of the executable. – Coffee on Mars Feb 17 '11 at 14:44
  • @David: I accepted the answer because I'm believing that there is no way to copy the memory space of the dll in a clean way, and the comments showed an "hacky" way to circumvent the limitation.If a cleaner method isn't available, I'll accept the "you can't do it" answer. – Coffee on Mars Feb 17 '11 at 14:49
  • @Coffee You can do it, it's not that bad, I have done it! Steve's 2nd comment, my answer, and MSalters excellent comment to my answer are all solutions. I don't mind what you do and which answer you accept, I just want to help! And I think you can do this. I implemented such a solution because a DLL of mine was not threadsafe, but I needed to use it in a multi-threaded situation for performance reasons. I've since made it threadsafe and reverted to a single instance of the DLL in my process. – David Heffernan Feb 17 '11 at 14:56
6

The sharing of static resources between all threads attached to a single DLL within a process conspires against you here.

However, there is a trick to achieve this. So long as DLLs have different names, then the system regards them as being different and so separate instances of code and data are created.

The way to achieve this is, for each thread, copy the DLL to a temporary file and load from there with LoadLibrary. You have to use explicit linking (GetProcAddress) rather than lib files but that's really the only way.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 2
    A variation would be a wrapper DLL that exposes the same interface, but which uses thread-local storage to forward each call to a per-thread copy of the DLL. This isolates all the trickery in the wrapper DLL. – MSalters Feb 17 '11 at 14:53