Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
0.7
-
None
-
Windows platform, native C++ client example
Description
Using one of the existing examples that has a line such as
"connection.close();"
change to
"if (connection) connection.close();"
causes error:
Error 2 error LNK2019: unresolved external symbol "__declspec(dllimport)public: __thiscall qpid::messaging::Handle<class
qpid::messaging::ConnectionImpl>::operator bool(void)const "(_imp??B?$Handle@VConnectionImpl@messaging@qpid@@@messaging@qpid@@QBE_NXZ)
referenced in function __catch$_main$0 client.obj messaging_clien
The missing routine undecorates to:
"public: __thiscall qpid::messaging::Handle<class qpid::messaging::ConnectionImpl>::operator bool(void)const "
I think the problem is that the messaging Connection class has a template Handle class in its interface, and then this interface is exported by a DLL. At DLL-compile time the DLL source code never instantiates the Handle class template and thus has no actual instance of Handle to export in the DLL. On a Linux build the instances of Handle are created on the client host system and are not imported from a library - but this is purely a guess. See also http://www.codeproject.com/kb/cpp/templatesourceorg.aspx
--------------
Possible fixes
1. Add a separate compilation unit to Windows builds that creates actual instances of Handle<>. Then export these in the DLL to satisfy the link.
This may work but it does not sound easy to support in the long run.
2. Define the function definitions in Connection proper and not let the work fall into class Handle. In Connection.cpp adding
QPID_MESSAGING_EXTERN operator bool() const
solves the issue. This same pattern applies to several functions in each of Connection, Receiver, Sender, and Session.
This would probably work in Linux, too, but could be conditionaled to only be active in Windows.
If anyone has some other ideas I'd love to hear them. Also, is having a template class in a Messaging library interface a good idea?