I am in the process of taking a large body of code (~450k lines) that
was originally written under Borland C++ 4.52 (for 16-bit Windows) and
making it work under Visual C++ 6.0 (for 32-bit, obviously).
Because BC452 is quite old, the syntax that made templates tick under
BC452 no longer works today. One of the problems I'm having is that I
cannot understand why I'm getting the following VC6 warning.
c:\wam\tip\lib\inc\prnt_job.hpp(75) : warning C4251: 'm_RowCache' :
class 'OwnerUtiList<struct PrintJobRowData>' needs to have
dll-interface to be used by clients of class 'PrintJob'
The specified class is a compiler generated class based on the
instantiation of the OwnerUtiList template. The OwnerUtiList template
is declared like this:
template < class T >
class DLLCLASS OwnerUtiList : public OwnerUtiListBase < T >
The 'DLLCLASS' macro boils down to _declspec (dllexport). What more
can I do to cause the compiler generated class to have a
dll-interface?
Thanks,
Andy
You can export a class or a template specialization, but you can't
export a primary template, because there's nothing to export. (I'm
talking about DLL exporting here, not the C++ "export" keyword which
is something different.)
You can probably ignore the C4251. The compiler will instantiate the
template when compiling code that uses it (the "clients"), so if you
don't mind each dynamically linked component having its own copy of
the generated template code, you should be fine. If you would like to
share one copy among all the dynamically linked components, you'll
need to explicitly instantiate the specializations you need and export
them from some common DLL everybody links to. For example, this is
what MS does with basic_string<char>, basic_string<wchar_t>, and other
specializations, which you'll find in msvcp60.dll.
--
Doug Harrison
dHar...@worldnet.att.net
Visual C++ MVP
Thanks for your reply.
Since the generated class will be 're-generated' in each linkage
module, I guess it's not really neccesary to export them. But how do
I convince the compiler that I don't really want to export the class
they're warning me about? I want to make the warning go away without
the drastic step of using a #pragma warning (disable : 4251).
I have the following classes, remembering that DLLCLASS is #defined as
'__declspec(dllexport)':
--- uti_rcp.hpp ---
template <class T> class DLLCLASS UtiRCPointer {...}
class DLLCLASS UtiRCObjectBase {...}
--- utistr.hpp ---
class DLLCLASS UtiString
{
private:
class DLLCLASS UtiStringData : public UtiRCObjectBase {...};
UtiRCPointer<UtiStringData> m_spString;
};
I stripped out the body 'cause I believe them to be irrelevant to the
discussion. When I compile this code (for a DLL target) I get the
following level 1 warning in each file that includes 'utistr.hpp'.
c:\wam\tip\lib\inc\utistr.hpp(289) : warning C4251: 'm_spString' :
class 'UtiRCPointer<class UtiString::UtiStringData>' needs to have
dll-interface to be used by clients of class 'UtiString'
Thanks,
Andy
>Doug,
>
>Thanks for your reply.
>
>Since the generated class will be 're-generated' in each linkage
>module, I guess it's not really neccesary to export them. But how do
>I convince the compiler that I don't really want to export the class
>they're warning me about? I want to make the warning go away without
>the drastic step of using a #pragma warning (disable : 4251).
>
>I have the following classes, remembering that DLLCLASS is #defined as
>'__declspec(dllexport)':
>
> --- uti_rcp.hpp ---
>template <class T> class DLLCLASS UtiRCPointer {...}
You can get rid of the DLLCLASS above, because it has no effect on a
primary class template.
>class DLLCLASS UtiRCObjectBase {...}
>
> --- utistr.hpp ---
>class DLLCLASS UtiString
>{
> private:
> class DLLCLASS UtiStringData : public UtiRCObjectBase {...};
> UtiRCPointer<UtiStringData> m_spString;
>};
>
>I stripped out the body 'cause I believe them to be irrelevant to the
>discussion. When I compile this code (for a DLL target) I get the
>following level 1 warning in each file that includes 'utistr.hpp'.
>
> c:\wam\tip\lib\inc\utistr.hpp(289) : warning C4251: 'm_spString' :
> class 'UtiRCPointer<class UtiString::UtiStringData>' needs to have
> dll-interface to be used by clients of class 'UtiString'
Well, I take the simple approach of disabling the warning. I've yet to
have any problems resulting from this. You might try exporting the
specializations you need, but the problem with that, of course, is
that you're probably always needing new specializations. You can also
try ensuring that no inline member functions use the member provoking
the C4251. This includes compiler-generated default ctor, copy ctor,
dtor, and assignment operator, if any. The member in question is
private, so the compiler could assume that if no inline functions use
it, and the class has no friends, client context doesn't have access
to it. You could also try exporting individual class members, rather
than the whole class. I do that fairly often. I have no idea how
successful any of this will be, though.
Is what I've done.
>Well, I take the simple approach of disabling the warning. I've yet to
>have any problems resulting from this. You might try exporting the
>specializations you need, but the problem with that, of course, is
>that you're probably always needing new specializations. You can also
>try ensuring that no inline member functions use the member provoking
>the C4251. This includes compiler-generated default ctor, copy ctor,
>dtor, and assignment operator, if any. The member in question is
>private, so the compiler could assume that if no inline functions use
>it, and the class has no friends, client context doesn't have access
>to it. You could also try exporting individual class members, rather
>than the whole class. I do that fairly often. I have no idea how
>successful any of this will be, though.
I also, for now, disabled the specific warning. I figured that if I
could get along for the past however many years without the compiler
telling me to provide a dll-interface, then I could probably do it for
another however many years.
I really wish the compiler would be smart enough to not bother issuing
the warning for template instantiations, though.
Thanks for helping out.
Andy