For instance, winsock libs works great across all versions of the visual studio. But I am having real trouble to provide a consistent binary across all the versions. The dll compiled with VS 2005 won’t work when linked to an application written in 2008. I upgraded both 2k5 and 2k8 to SP1, but the results haven’t changed much. It works some what ok. But when they include this with a C# app, the C# app gets access violation errors, but with classic C++ application it works fine.
Is there a strategy that I should know when I provide dlls ?
First, dont pass anything other than plain old data accross DLL boundries. i.e. structs are fine. classes are not. Second, make sure that ownership is not transferred – i.e. any structs passed accross the dll boundry are never deallocated outside the dll. So, if you dll exports a X* GetX() function, there is a corresponding FreeX(X*) type function ensuring that the same runtime that allocated is responsible for de-allocation.
Next: Get your DLLs to link to the static runtime. Putting together a project comprimising dls from several 3rd parties, each linked to and expecting different runtimes, potentially different to the runtime expected by the app, is a pain, potentially forcing the installer software to install runtimes for 7.0, 7.1, 8.0 and 9.0 – several of which exist in different service packs which may or may not cause issues. Be kind – statically link your dll projects.
— Edit: You cannot export a c++ class directly with this approach. Sharing class definitions between modules means you MUST have a homogeneous runtime environment as different compilers or versions of compilers will generate decorated names differently.
You can bypass this restriction by exporting your class instead as a COM style interface… which is to say, while you cannot export a class in a runtime independent way, you CAN export an ‘interface’, which you can easilly make by declaring a class containing only pure virtual functions…
In your class definition, you inherit from this interface:
You can export interfaces like this by making C factory methods:
This is a very lightweight way of exporting compiler version and runtime independent class versions. Note that you still cannot delete one of these. You Must include a release function as a member of the dll or the interface. As a member of the interface it could look like this:
You can take this idea and run further with it – inherit your interface from IUnknown, implement ref counted AddRef and Release methods as well as the ability to QueryInterface for v2 interfaces or other features. And finally, use DllCreateClassObject as the means to create your object and get the necessary COM registration going. All this is optional however, you can easilly get away with a simple interface definition accessed through a C function.