Note that there are some explanatory texts on larger screens.

plurals
  1. POWhen exporting STL std::basic_string template from DLL, I get a LNK2005 error
    primarykey
    data
    text
    <p>OK, so I've read several question and articles about this topic, and I feel like I understand the basics, but I'm still having trouble.</p> <p>I have a DLL that exports a class that has a std::string as a member. My main program contains classes that also have strings, and it uses the DLL.</p> <p>If I compile the DLL in VS2010, I get the following warnings:</p> <pre><code>warning C4251: 'MyClass::data' : class 'std::basic_string&lt;_Elem,_Traits,_Ax&gt;' needs to have dll-interface to be used by clients of class 'MyClass' </code></pre> <p>When I compile the EXE, I get the same warnings, but there are no errors, and the program compiles and runs. In reality, it's a large project, so I get like 40 warnings, and I'm not too keen on that. (As a side-observation, these warnings are not present when compiled with VS2008)</p> <p>So, I read about that warning, and it lead me to this MS article: <a href="http://support.microsoft.com/default.aspx?scid=KB;EN-US;168958" rel="noreferrer">http://support.microsoft.com/default.aspx?scid=KB;EN-US;168958</a> which tells how to export a STL template from a DLL to satisfy the warnings I was getting.</p> <p>The problem is, when I add the following lines to remove the warnings:</p> <pre><code>EXPIMP_TEMPLATE template class DECLSPECIFIER std::allocator&lt;char&gt;; EXPIMP_TEMPLATE template class DECLSPECIFIER std::basic_string&lt; char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;; </code></pre> <p>the DLL compiles with no warnings, but when I compile my EXE, the linker throws a fit:</p> <pre><code>2&gt;SampleDLL.lib(SampleDLL.dll) : error LNK2005: "public: __thiscall std::basic_string&lt;char,struct std::char_traits&lt;char&gt;,class std::allocator&lt;char&gt; &gt;::~basic_string&lt;char,struct std::char_traits&lt;char&gt;,class std::allocator&lt;char&gt; &gt;(void)" (??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ) already defined in OtherClass.obj 2&gt;SampleDLL.lib(SampleDLL.dll) : error LNK2005: "public: unsigned int __thiscall std::basic_string&lt;char,struct std::char_traits&lt;char&gt;,class std::allocator&lt;char&gt; &gt;::size(void)const " (?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ) already defined in OtherClass.obj </code></pre> <p>Both the DLL and the EXE are compiled with the same code generation options. I can use MT on both or MD, and the results are the same.</p> <p>I am including the code from a minimized sample program in case I left anything out above.</p> <p><strong>My main question: Can I fix the LNK2005 errors, or is it safe to just ignore the C4251 warnings?</strong></p> <p><strong>Edit:</strong> So I've read a little more, and it looks like if the std::string that the DLL class uses is a private variable that is only accessed by member functions, it may be safe to ignore the warning... Any comments on this? Is this a step in the right direction?</p> <p>DLL code: </p> <pre><code>#pragma once #include &lt;exception&gt; #include &lt;string&gt; #ifdef SAMPLEDLL_EXPORTS # define DECLSPECIFIER __declspec(dllexport) # define EXPIMP_TEMPLATE #else # define DECLSPECIFIER __declspec(dllimport) # define EXPIMP_TEMPLATE extern #endif //disable warnings on extern before template instantiation (per MS KB article) #pragma warning (disable : 4231) //std::basic_string depends on this allocator, so it must also be exported. EXPIMP_TEMPLATE template class DECLSPECIFIER std::allocator&lt;char&gt;; //std::string is a typedef, so you cannot export it. You must export std::basic_string EXPIMP_TEMPLATE template class DECLSPECIFIER std::basic_string&lt; char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;; #pragma warning (default : 4231) class DECLSPECIFIER MyClass { public: std::string getData(); //returns 'data', body in CPP file private: std::string data; int data2; }; //in SampleDLL.cpp file... std::string MyClass::getData() { return data; } </code></pre> <p>EXE code: </p> <pre><code>#include &lt;iostream&gt; #include "SampleDLL.h" using namespace std; void main() { MyClass class1; cout &lt;&lt; class1.getData() &lt;&lt; endl; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload