#14741 closed defect (fixed)

unresolved externals for wxWindowList with VS11 (2012) and wxUSE_STD_CONTAINERS

Reported by: hajokirchhoff Owned by:
Priority: normal Milestone: 2.9.5
Component: wxMSW Version:
Keywords: vs11 msvs dll Cc:
Blocked By: Blocking:
Patch: yes

Description

I'm trying to compile my application with Visual Studio 2012 and get the following unresolved externals from std::list<wxWindow*> when I have wxUSE_STD_CONTAINERS defined:

This and others:

 "__declspec(dllimport) public: static struct std::_List_node<class
wxWindow *,void *> * & __cdecl std::_List_val<struct
std::_List_simple_types<class wxWindow *> >::_Nextnode(struct
std::_List_node<class wxWindow *,void *> *)"
(__imp_?_Nextnode@?$_List_val@U?$_List_simple_types@PEAVwxWindow@@@std@@@
std@@SAAEAPEAU?$_List_node@PEAVwxWindow@@PEAX@2@PEAU32@@Z) referenced in
function "public: class std::_List_const_iterator<class
std::_List_val<struct std::_List_simple_types<class wxWindow *> > > &
__cdecl std::_List_const_iterator<class std::_List_val<struct
std::_List_simple_types<class wxWindow *> > >::operator++(void)"
(??E?$_List_const_iterator@V?$_List_val@U?$_List_simple_types@PEAVwxWindow
@@@std@@@std@@@std@@QEAAAEAV01@XZ)

Here is what I think happens:
In pre VS11 when an exported class derived from a template, the template instance would in some instances be automatically exported as well. This seems no longer to be the case.

window.h, line 145 (approx) has the following line

WX_DECLARE_LIST_3(wxWindow, wxWindowBase, wxWindowList, wxWindowListNode, class WXDLLIMPEXP_CORE);

This declares a class _dllexport/import wxWindowList, which derives from std::list<wxWindow*> through some macro magic (WX_DECLARE_LIST_XO in list.h, line 147)

The declaration is

class WXDLLIMPEXP_CORE wxWindowList:public std::list<wxWindow*> ...

Pre VS11 (VS9, Visual Studio 2008 to be precise) would seemingly export all std::list members as well. But when I compile this code:

wxWindow *window;
for (wxWindowList::iterator i = window->GetChildren().begin(); i != window->GetChildren().end(); ++i)

I get the unresolved externals above.

Any Ideas? The way I see it, we have two choices:

  1. Make wxWindowList a template itself or a header-only class. It is currently being exported and there is a forward export declaration in utils.h, line 57.
  2. Explicitly instantiate std::list<wxWindow*> and export it. I think this is possible with a non-standard Microsoft extension. This explicit instantiation and export statement should reside somewhere in the wx-core sources.

Attachments (1)

wxlist-vs11-trac14741.patch download (4.4 KB) - added by hajokirchhoff 18 months ago.
Patch making wxList-classes header only to avoid unresolved externals on VS11

Download all attachments as: .zip

Change History (6)

comment:1 Changed 18 months ago by vadz

  • Keywords msvs dll added; visual studio removed
  • Milestone set to 3.0

This is really strange, I have trouble believing that Microsoft could have broken backwards compatibility so badly and that nobody noticed it. But I don't see any other explanation neither...

Anyhow, we do have to fix it and if we can just remove export declaration from wxWindowList to fix this, it would be the simplest and the best, of course. Could you please confirm that it works (and attach a patch doing this) please?

TIA!

comment:2 Changed 18 months ago by hajokirchhoff

  • Patch set

Relatively straightforward though a bit more complicated than I expected: The wxList classes are now header only and are no longer exported, but the _WX_LIST_HELPER classes are still being exported. They do not derive from a template class and don't have the problem described here.

Regarding "broken backwards compatibility...": my guess is that this was never supposed to work anyway and only worked because of the previous way the MS compiler instantiated templates. We probably disabled the warning "base class needs to have dll export to be able to use members...", which showed up in so many annoying places.

I've attached the patch. It works fine here now.

Changed 18 months ago by hajokirchhoff

Patch making wxList-classes header only to avoid unresolved externals on VS11

comment:3 Changed 18 months ago by hajokirchhoff

On second thought: I tested the patch with wxUSE_STD_CONTAINERS but not without. The changes should be transparent though, as I changed only the #definition of the wxUSE_STD_CONTAINERS variant (I hope).

comment:4 Changed 18 months ago by vadz

  • Milestone changed from 3.0 to 2.9.5

Thanks, I'll try to test and apply it soon.

comment:5 Changed 17 months ago by VZ

  • Resolution set to fixed
  • Status changed from new to closed

(In [72940]) Fix link errors with VC 11 in DLL STL build.

Don't declare wxWindowList as DLL-exported. It's unnecessary and appears to
create problems for VC 11.

Closes #14741.

Note: See TracTickets for help on using tickets.