My product is a C++ library, which, on Windows, is distributed as a dll. It makes very little use of the c-runtime (basic iostream and that's it), so I'm sure that all recent versions of the CRT will be fine.
Since my client is supposed to build his application using my dll, I don't want to impose upon him any specific runtime version. I'd like my dll to bind to whatever runtime library version my client's app is using (and I can assume that he'll use dynamic linking for his CRT). After all, isn't that what dynamic linking is all about? Is that possible?
EDIT: linking the dll against the static runtime libs won't work either, because then the static runtime (from the dll) and the dynamic runtime (from the client's application) will be mixed, which is bad.
EDIT: What I'm mainly asking is how do I tell the runtime loader to link my dll against whatever CRT the application is linked with? Something with the manifest, perhaps? More generally, my question is how to build a nicely-behaving dll, that's to be used by clients building they're own applications?
EDIT: Thanks to the advice in the answers, I've transferred all references to std classes into inlined functions in my headers, and linked my dll with the static runtime libraries. It now seems to work even in applications linked with different CRT versions.
Runtime is the version of the CLR (or . NET framework) the DLL needs (usually as a minimum), version is the DLL's version. So long as you have the minimum runtime installed, it should be usable. However as a general rule it is usually best to select the latest version of the library for the latest runtime support etc.
DllMain is not mandatory. If you have some initialization code required to run when loading the dll, you should create a DllMain function, and treat the initialization there. Otherwise it's not required.
There's no real way to ensure your DLL works with multiple runtimes -- any of the types that change between them can lead to incompatibilities. For instance, the size of an object can change, or the location of members in them. There is very little room in C++ for this kind of thing.
The best thing you can do is statically link to the runtime and ensure the exported API is limited to types strictly under your control -- no passing std::string
to a function, no stdlib types as members, and don't new
in one DLL and delete
in another. Don't mix inline and exported functions (including constructors/destructors) for the same object, because member order and padding might change between compilers. The pimpl idiom might help here.
If you expose any C++ objects across DLL boundaries then this is simply not possible. What you can do (and we use a 3rd-party DLL that does this) is build your library in multiple configurations (32-bit/64-bit, debug/release, static/dynamic runtime, static/dynamic library) to satisfy as many people as possible. This may be a bit tedious to setup at first, but once you have all the configurations setup it's just a matter of building them all. Of course you also need to consider which runtime you are building against (vc8, vc9, vc10, etc), so if you want to cover all the bases you could have quite a lot of configurations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With