]> git.saurik.com Git - wxWidgets.git/commitdiff
fix linking problems due to MSVC implicitly considering template classes specializati...
authorVadim Zeitlin <vadim@wxwidgets.org>
Thu, 30 Oct 2008 23:04:29 +0000 (23:04 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Thu, 30 Oct 2008 23:04:29 +0000 (23:04 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@56602 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/buffer.h
include/wx/string.h
src/common/string.cpp
src/common/ustring.cpp

index 32443237373ac92b4429d53f69cfe227f3dac051..2f8bc6486660f52b7a366bbcd2bfdcab441a0659 100644 (file)
@@ -27,7 +27,7 @@ class WXDLLIMPEXP_FWD_BASE wxCStrData;
 // ----------------------------------------------------------------------------
 
 template <typename T>
-class WXDLLIMPEXP_BASE wxCharTypeBuffer
+class wxCharTypeBuffer
 {
 public:
     typedef T CharType;
@@ -37,7 +37,7 @@ public:
         if ( str )
             m_data = new Data(wxStrdup(str));
         else
-            m_data = &NullData;
+            m_data = GetNullData();
     }
 
     wxCharTypeBuffer(size_t len)
@@ -64,7 +64,7 @@ public:
     //     that ref-counting is used, it's not really needed.
     CharType *release() const
     {
-        if ( m_data == &NullData )
+        if ( m_data == GetNullData() )
             return NULL;
 
         wxASSERT_MSG( m_data->m_owned, _T("can't release non-owned buffer") );
@@ -121,7 +121,7 @@ public:
         if ( !str )
             return false;
 
-        if ( m_data == &NullData )
+        if ( m_data == GetNullData() )
         {
             m_data = new Data(str);
         }
@@ -167,30 +167,27 @@ private:
     };
 
     // placeholder for NULL string, to simplify this code
-    // NB: this is defined in string.cpp, not (non-existent) buffer.cpp
-#ifdef __MINGW32__
-    // MinGW requires explicit WXDLLIMPEXP_DATA_BASE to avoid compilation
-    // errors
-    static WXDLLIMPEXP_DATA_BASE(Data) NullData;
-#else
-    // but Visual C++ doesn't like it
-    static Data NullData;
-#endif
+    static Data *GetNullData()
+    {
+        static Data s_nullData(NULL);
+
+        return &s_nullData;
+    }
 
     void IncRef()
     {
-        if ( m_data == &NullData ) // exception, not ref-counted
+        if ( m_data == GetNullData() ) // exception, not ref-counted
             return;
         m_data->m_ref++;
     }
 
     void DecRef()
     {
-        if ( m_data == &NullData ) // exception, not ref-counted
+        if ( m_data == GetNullData() ) // exception, not ref-counted
             return;
         if ( --m_data->m_ref == 0 )
             delete m_data;
-        m_data = &NullData;
+        m_data = GetNullData();
     }
 
 private:
@@ -199,7 +196,7 @@ private:
 
 WXDLLIMPEXP_TEMPLATE_INSTANCE_BASE( wxCharTypeBuffer<char> )
 
-class WXDLLIMPEXP_BASE wxCharBuffer : public wxCharTypeBuffer<char>
+class wxCharBuffer : public wxCharTypeBuffer<char>
 {
 public:
     typedef wxCharTypeBuffer<char> wxCharTypeBufferBase;
@@ -216,7 +213,7 @@ public:
 #if wxUSE_WCHAR_T
 WXDLLIMPEXP_TEMPLATE_INSTANCE_BASE( wxCharTypeBuffer<wchar_t> )
 
-class WXDLLIMPEXP_BASE wxWCharBuffer : public wxCharTypeBuffer<wchar_t>
+class wxWCharBuffer : public wxCharTypeBuffer<wchar_t>
 {
 public:
     typedef wxCharTypeBuffer<wchar_t> wxCharTypeBufferBase;
@@ -342,7 +339,7 @@ private:
 };
 
 
-class WXDLLIMPEXP_BASE wxMemoryBuffer
+class wxMemoryBuffer
 {
 public:
     // ctor and dtor
index 43dfbcb175a75bf17afccb348fe6e057ed6f0bf6..10729ed6ebab73d6b4391c70a398e284ac6463a7 100644 (file)
@@ -3605,7 +3605,7 @@ private:
 #endif // !wxUSE_STL_BASED_WXSTRING
 
 template<typename T>
-class WXDLLIMPEXP_BASE wxStringTypeBufferBase
+class wxStringTypeBufferBase
 {
 public:
     typedef T CharType;
@@ -3645,8 +3645,7 @@ protected:
 };
 
 template<typename T>
-class WXDLLIMPEXP_BASE wxStringTypeBufferLengthBase
-    : public wxStringTypeBufferBase<T>
+class wxStringTypeBufferLengthBase : public wxStringTypeBufferBase<T>
 {
 public:
     wxStringTypeBufferLengthBase(wxString& str, size_t lenWanted = 1024)
@@ -3750,25 +3749,57 @@ typedef wxStringInternalBufferLength          wxUTF8StringBufferLength;
 
 WXDLLIMPEXP_TEMPLATE_INSTANCE_BASE( wxStringTypeBufferBase<char> )
 
-class WXDLLIMPEXP_BASE wxUTF8StringBuffer : public wxStringTypeBufferBase<char>
+// Note about inlined dtors in the classes below: this is done not for
+// performance reasons but just to avoid linking errors in the MSVC DLL build
+// under Windows: if a class has non-inline methods it must be declared as
+// being DLL-exported but, due to an extremely interesting feature of MSVC 7
+// and later, any template class which is used as a base of a DLL-exported
+// class is implicitly made DLL-exported too, as explained at the bottom of
+// http://msdn.microsoft.com/en-us/library/twa2aw10.aspx (just to confirm: yes,
+// _inheriting_ from a class can change whether it is being exported from DLL)
+//
+// But this results in link errors because the base template class is not DLL-
+// exported, whether it is declared with WXDLLIMPEXP_BASE or not, because it
+// does have only inline functions. So the simplest fix is to just make all the
+// functions of these classes inline too.
+
+class wxUTF8StringBuffer : public wxStringTypeBufferBase<char>
 {
 public:
     wxUTF8StringBuffer(wxString& str, size_t lenWanted = 1024)
         : wxStringTypeBufferBase<char>(str, lenWanted) {}
-    ~wxUTF8StringBuffer();
+    ~wxUTF8StringBuffer()
+    {
+        wxMBConvStrictUTF8 conv;
+        size_t wlen = conv.ToWChar(NULL, 0, m_buf);
+        wxCHECK_RET( wlen != wxCONV_FAILED, "invalid UTF-8 data in string buffer?" );
+
+        wxStringInternalBuffer wbuf(m_str, wlen);
+        conv.ToWChar(wbuf, wlen, m_buf);
+    }
 
     DECLARE_NO_COPY_CLASS(wxUTF8StringBuffer)
 };
 
 WXDLLIMPEXP_TEMPLATE_INSTANCE_BASE( wxStringTypeBufferLengthBase<char> )
 
-class WXDLLIMPEXP_BASE wxUTF8StringBufferLength
-    : public wxStringTypeBufferLengthBase<char>
+class wxUTF8StringBufferLength : public wxStringTypeBufferLengthBase<char>
 {
 public:
     wxUTF8StringBufferLength(wxString& str, size_t lenWanted = 1024)
         : wxStringTypeBufferLengthBase<char>(str, lenWanted) {}
-    ~wxUTF8StringBufferLength();
+    ~wxUTF8StringBufferLength()
+    {
+        wxCHECK_RET(m_lenSet, "length not set");
+
+        wxMBConvStrictUTF8 conv;
+        size_t wlen = conv.ToWChar(NULL, 0, m_buf, m_len);
+        wxCHECK_RET( wlen != wxCONV_FAILED, "invalid UTF-8 data in string buffer?" );
+
+        wxStringInternalBufferLength wbuf(m_str, wlen);
+        conv.ToWChar(wbuf, wlen, m_buf, m_len);
+        wbuf.SetLength(wlen);
+    }
 
     DECLARE_NO_COPY_CLASS(wxUTF8StringBufferLength)
 };
index 04a606a3c563b308768b9678347732562de43ac4..fcdca45d58a08aa3c98e32844a8293d93d144946 100644 (file)
@@ -2096,48 +2096,3 @@ int wxString::Freq(wxUniChar ch) const
     }
     return count;
 }
-
-// ----------------------------------------------------------------------------
-// wxUTF8StringBuffer
-// ----------------------------------------------------------------------------
-
-#if wxUSE_UNICODE_WCHAR
-wxUTF8StringBuffer::~wxUTF8StringBuffer()
-{
-    wxMBConvStrictUTF8 conv;
-    size_t wlen = conv.ToWChar(NULL, 0, m_buf);
-    wxCHECK_RET( wlen != wxCONV_FAILED, "invalid UTF-8 data in string buffer?" );
-
-    wxStringInternalBuffer wbuf(m_str, wlen);
-    conv.ToWChar(wbuf, wlen, m_buf);
-}
-
-wxUTF8StringBufferLength::~wxUTF8StringBufferLength()
-{
-    wxCHECK_RET(m_lenSet, "length not set");
-
-    wxMBConvStrictUTF8 conv;
-    size_t wlen = conv.ToWChar(NULL, 0, m_buf, m_len);
-    wxCHECK_RET( wlen != wxCONV_FAILED, "invalid UTF-8 data in string buffer?" );
-
-    wxStringInternalBufferLength wbuf(m_str, wlen);
-    conv.ToWChar(wbuf, wlen, m_buf, m_len);
-    wbuf.SetLength(wlen);
-}
-#endif // wxUSE_UNICODE_WCHAR
-
-// ----------------------------------------------------------------------------
-// wxCharBufferType<T>
-// ----------------------------------------------------------------------------
-
-#ifndef __VMS_BROKEN_TEMPLATES
-template<>
-#endif
-wxCharTypeBuffer<char>::Data
-wxCharTypeBuffer<char>::NullData(NULL);
-
-#ifndef __VMS_BROKEN_TEMPLATES
-template<>
-#endif
-wxCharTypeBuffer<wchar_t>::Data
-wxCharTypeBuffer<wchar_t>::NullData(NULL);
index c0cae8f58de797fd7940d544fe787b0b69d529a2..a9b9241eb475551e2e43486503eaf6a1a64f5fc3 100644 (file)
@@ -542,16 +542,3 @@ wxU16CharBuffer wxUString::utf16_str() const
     
     return result;    
 }
-
-
-#if SIZEOF_WCHAR_T != 2
-template<>
-wxCharTypeBuffer<wxChar16>::Data
-wxCharTypeBuffer<wxChar16>::NullData(NULL);
-#endif
-
-#if SIZEOF_WCHAR_T != 4
-template<>
-wxCharTypeBuffer<wxChar32>::Data
-wxCharTypeBuffer<wxChar32>::NullData(NULL);
-#endif