views:

203

answers:

2

Hi there.

I wrote a class library in C++ and successfully compiled it in Linux with g++ as a shared object, then created a few apps that use it. Now I have to port it to VS2008. I gave all the classes the required __declspec(dllexport) prefixes, then tried to compile it. I get a pile of warnings, which basically have to do with:

  1. my custom exception classes, derived from std::runtime_error, which yield: "warning C4275: non dll-interface class 'std::runtime_error' used as base for dll-interface class 'cci::FileOperationException'". How am I supposed to make a standard library class dll-exportable?
  2. exception specifications in member functions' declarations, which cause "warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)". I read somewhere that VS doesn't support these, and that it does somewhere else. How very confusing.

I read people saying that exporting classes in a DLL is generally a Bad Idea, that there's a myriad of things that can go wrong, and now I have my head full of concepts like binary incompatibility, dll hell, compiler version mismatches etc, and to be honest I can't really make heads or tails of it. What is the correct, safe and easy way to create a shared class library in Windows, then?

Thanks.

+2  A: 

I maintain a C++ class library that is typically used as DLL on Windows, so it can be done. Regarding your issues:

  1. That doesn't happen in my library. Perhaps you need to be using the /MD and /MDd build options? That way your C++ run-time-library comes from a DLL, too, which is the sort of picky thing VC++ is famous for.

  2. Don't use throw-specs. They are evil. If you feel you must do it anyway, just put something like this in a header file that every module includes before it gets to code that uses throw-specs.

#pragma warning(disable: 4290)

Warren Young
I am using /MD, doesn't help. Whacked all the ES's though, after reading the article, thanks.
neuviemeporte
More generally, then, you might download MySQL++ and take a look at its project settings to see why mine works and yours doesn't. MySQL++ does something similar to your library: see lib/exceptions.h, where we derive a custom mysqlpp::Exception class from std::exception.
Warren Young
That's because apparently std::exception *is* exported in Microsoft-land. Changed mine to it, warnings are gone.
neuviemeporte
A: 

First you should ask yourself if you really need a dynamic library here. Static libraries or or even better including the source code directly in your project is a good solution that comes without those problems.

If you really need the DLL, the way I would do this (given much time) is wrapping your class in a C interface. You can then recreate your old C++ interface as a C++ header only library that interacts only with the C calls exported from the DLL. A bonus feature for this approach is that it will be trivial to use your library from almost any programming language since importing C functions from DLL's is highly supported.

Another way to go would be to use COM but since you are porting from Linux this is probably not an option.

Laserallan