Warning C4251 when building a DLL that exports a class containing an ATL::CString member
Asked Answered
D

4

24

I am converting an ATL-based static library to a DLL and am getting the following warning on any exported classes that use the ATL CString class (found in atlstr.h):

warning C4251: 'Foo::str_' : class 'ATL::CStringT' needs to have dll-interface to be used by clients of class 'Foo'

I am correctly declaring the Foo class as exported via __declspec(dllexport). Is this a warning I can safely ignore or am I doing something wrong? The DLL project settings are set to dynamically link with ATL, but this doesn't seem to make any difference.

For example:

#ifdef DLLTEST_EXPORTS
#define DLLTEST_API __declspec(dllexport)
#else
#define DLLTEST_API __declspec(dllimport)
#endif

// This class is exported from the DLLTest.dll
class DLLTEST_API Foo
{
public:
 Foo();
 CString str_; // WARNING C4251 HERE
};

All clients of this DLL will also be using ATL.

Downwash answered 25/1, 2010 at 14:4 Comment(1)
If you are able to ensure both the library and the client is built against the exact same version of the ATL library, than you can ignore it.Pierson
G
20

This thread gives what I consider a better answer, by Doug Harrison (VC++ MVP):

[This warning is] emitted when you use a non-dllexported class X in a dllexported class Y. What's so bad about that? Well, suppose Y has an inline function y_f that calls a function x_f belonging to X that is not also inline. If y_f is inlined inside some client that doesn't statically link X, the link will fail, because x_f won't be found.

Galactometer answered 30/12, 2010 at 15:10 Comment(3)
Why then not only issue the warning if the not exported class is really used in an inline function? As it is now they force you to make your code messier in some way even if there is no problem because the private member is always used in non-inline functions.Stenograph
@Knitschi: (1) Technically I think the warnings are emitted by the compiler front end, that has no idea about inlining decisions, (2) I personally think this warning should be omitted altogether. Even when the unexported class is used in an inline function - the damage is a linking error, not a runtime one, and should be immediately fixable.Galactometer
WebArchive: web.archive.org/web/20170811142318/http://…Damaris
S
9

Here is a thread with a good discussion of this.

In short, the compiler is warning you that, in effect, your exported class does not seperate the interface from the implementation. If the members in question are not accessible to the clients, make them private and #pragma away the warning for that member/class. If the members are accessible and used by clients, then you will need to provide indirect access to the members through accessors and mutators.

Stephi answered 25/1, 2010 at 14:10 Comment(1)
So if the warned objects are already private to the class, we can safely ignore this warning?Bony
A
0

I usually get this warning when I make the silly mistake of building the DLL with runtime library Single/Multithreaded instead of Single/MultithreadedDLL. You might want to check that in your project settings.

Ahl answered 29/1, 2010 at 0:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.