Qpid
  1. Qpid
  2. QPID-2926

Simple example code does not link under Windows

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 0.7
    • Fix Version/s: 0.7
    • Component/s: C++ Client
    • Labels:
      None
    • Environment:

      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

      { return qpid::messaging::Handle<ConnectionImpl>::operator bool(); }

      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?

        Activity

          People

          • Assignee:
            Chuck Rolke
            Reporter:
            Chuck Rolke
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development