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

        Hide
        Chuck Rolke added a comment -

        Here's my second suggestion. It is actually Possible Fix #1 from the last post:

        In a brand new windows-only qpidmessaging source file

        void HandleInstantiatorDoNotCall(void)

        { // This function exists to instantiate various template Handle // bool functions. The instances are then available to // the qpidmessaging DLL and subsequently exported. // This function must not be exported nor called called. // For further information refer to // https://issues.apache.org/jira/browse/QPID-2926 Connection connection; if (connection.isValid()) connection.close(); if (connection.isNull() ) connection.close(); if (connection ) connection.close(); if (!connection ) connection.close(); Receiver receiver; if (receiver.isValid()) receiver.close(); if (receiver.isNull() ) receiver.close(); if (receiver ) receiver.close(); if (!receiver ) receiver.close(); Sender sender; if (sender.isValid()) sender.close(); if (sender.isNull() ) sender.close(); if (sender ) sender.close(); if (!sender ) sender.close(); Session session; if (session.isValid()) session.close(); if (session.isNull() ) session.close(); if (session ) session.close(); if (!session ) session.close(); }

        Points:
        1. The code is in a new, windows-only qpidmessaging source file.
        2. The fix does not change any source module for linux and it changes no interface definitions.

        Show
        Chuck Rolke added a comment - Here's my second suggestion. It is actually Possible Fix #1 from the last post: In a brand new windows-only qpidmessaging source file void HandleInstantiatorDoNotCall(void) { // This function exists to instantiate various template Handle // bool functions. The instances are then available to // the qpidmessaging DLL and subsequently exported. // This function must not be exported nor called called. // For further information refer to // https://issues.apache.org/jira/browse/QPID-2926 Connection connection; if (connection.isValid()) connection.close(); if (connection.isNull() ) connection.close(); if (connection ) connection.close(); if (!connection ) connection.close(); Receiver receiver; if (receiver.isValid()) receiver.close(); if (receiver.isNull() ) receiver.close(); if (receiver ) receiver.close(); if (!receiver ) receiver.close(); Sender sender; if (sender.isValid()) sender.close(); if (sender.isNull() ) sender.close(); if (sender ) sender.close(); if (!sender ) sender.close(); Session session; if (session.isValid()) session.close(); if (session.isNull() ) session.close(); if (session ) session.close(); if (!session ) session.close(); } Points: 1. The code is in a new, windows-only qpidmessaging source file. 2. The fix does not change any source module for linux and it changes no interface definitions.
        Hide
        ASF subversion and git services added a comment -

        Commit 1525706 from Andrew Stitcher in branch 'qpid/trunk'
        [ https://svn.apache.org/r1525706 ]

        QPID-2926: Better solution for instantiating qpid::messaging::Handle<> specialisations

        Show
        ASF subversion and git services added a comment - Commit 1525706 from Andrew Stitcher in branch 'qpid/trunk' [ https://svn.apache.org/r1525706 ] QPID-2926 : Better solution for instantiating qpid::messaging::Handle<> specialisations

          People

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

            Dates

            • Created:
              Updated:
              Resolved:

              Development