Exporting template code = dangerous? (MSVC)
As I noted in another SO question, I came across this article. The issue came up when I compiled boost 1.40 via MSVC7.1 and several C4251 warnings popped up.
Now, after reading said article, I wonder: Is it generally discouraged to export template code, e.g.
class DLLEXPORT_MACRO AClass
{
public:
std::vector<int> getVecCopy() { return myVec; }
...
}
Say this code is compiled i开发者_如何学Gonto a DLL via MSVC7.1. Though this code does not produce any errors when referenced from other MSVC7.1 code, it is said that referencing this DLL in MSVC8 code produces crashes at runtime (memory alignment issues?).
Since this obviously is bad...what is a "best practice" to cope with the issue of exporting template code?
This appears to be a bad idea, as std::vector differs or might differ between compiler versions. However, this can likely fail at load time, because the name mangling of std::vector should differ across compiler versions (that's part of the rationale for name mangling).
This link-time failure is something you can't really enforce as a developer though, other than buying compilers that support it. The other solution is to keep template types out of DLL interfaces entirely. Put them into private members.
Note that the problem is not unique to templates. Imagine for a moment that std::string
is a UDT instead of a typedef, and provided by the compiler runtime. It could still change between compiler versions, and certainly between compiler vendors. It would still be unusable in a DLL interface.
For these reasons, the practical solutions are 0. use C, 1. use COM or 2. settle on a single compiler version.
Unfortunately there is really no way to export template code. External libraries typically just provide source code for any templates. Sometimes they have the templates use helper classes which are not templates to keep proprietary code hidden. But there's basically no way to do this.
精彩评论