std::unique_ptr pimpl in dll generates C4251 with visual studio
That is a very common issue with DLL classes, that use templates from std
.
Why does it happen?
Reason is very simple: standard specifies only guarantees, limitations and requirements. So you can be sure, that every C++ 11 compiler will provide std::unique_ptr
, that looks and works as described on this page. But everything else is implementation dependent.
The main problem is, that different implementations may (and usually, will) use a totally different structure for particular types. They use additional helper variables, different layout and so on. This may differ even between two versions of the same compiler. So if client code touches in any way member variables of your class, you need to provide DLL interface for them. That applies recursively to all types used by dllexport
ed class.
You may want to read this article on MSDN, that describes this problem with containers in mind.
This problem can be simplified to the following:
- If client code has no access to your data, disable this warning.
- If you have members, that are intended to use by client code, create wrapper, that is
dllexport
ed or use additional indirection withdllexport
ed methods. - Usually, you can use PIMPL to hide non-DLL types, but in your case it is not applicable, since you use non-exportable type to actually implement PIMPL.
Further reading:
- MSDN: How to export an instantiation of a STL class
- Microsoft DLL export and C++ templates
- SO: Exporting classes containing std:: objects from a dll
- SO: How to use an exported class in an STL template?
Instead of exporting the entire class, you could export public methods only:
class Framework
{
Framework(const Framework&) = delete;
Framework& operator=(const Framework&) = delete;
Framework(Framework&&) = delete;
Framework& operator=(Framework&&) = delete;
public:
EXPORT_API Framework();
EXPORT_API ~Framework();
private:
std::unique_ptr<FrameworkImpl> impl_;
};