Warm tip: This article is reproduced from stackoverflow.com, please click
algorithmic-trading c++ fix-protocol quickfix

QuickFix C++: Errors when compiling Acceptor

发布于 2020-12-08 01:41:33

Goal:

To compile the "Acceptor" program (server). When this is complete, to then compile an "initiator" (client) to then print a simple output to confirm that the two applications are communicating with each other (the requirements of which I have read through the QuickFix documentation and mostly understand).

Please note before posting this question, the QuickFix mailing list and SO have been consulted. A question with similar issues can be found at the following URL, however, the answers are still causing me some confusion: Compiling a quickfix program

Problem:

When attempting to compile the following sample Acceptor program exactly copied from http://www.quickfixengine.org/quickfix/doc/html/application.html, various errors have been appearing, as seen further below. The compilation command I used was:

g++ trade_server_test.cpp -std=c++11 -fexceptions -finline-functions -lquickfix -lpthread -lxml2

The program:

#include "quickfix/FileStore.h"
#include "quickfix/FileLog.h"
#include "quickfix/SocketAcceptor.h"
#include "quickfix/Session.h"
#include "quickfix/SessionSettings.h"
#include "quickfix/Application.h"

int main( int argc, char** argv )
{
    try
    {
        if(argc < 2) return 1;
        std::string fileName = argv[1];

        FIX::SessionSettings settings(fileName);

        MyApplication application;
        FIX::FileStoreFactory storeFactory(settings);
        FIX::FileLogFactory logFactory(settings);
        FIX::SocketAcceptor acceptor
          (application, storeFactory, settings, logFactory /*optional*/);
        acceptor.start();
        // while( condition == true ) { do something; }
        acceptor.stop();
        return 0;
    }
    catch(FIX::ConfigError& e)
    {
        std::cout << e.what();
        return 1;
    }
}

Error Outputs

The following errors are observed:

trade_server_test.cpp: In function ‘int main(int, char**)’:
trade_server_test.cpp:17:3: error: ‘MyApplication’ was not declared in this scope
   MyApplication application;
   ^~~~~~~~~~~~~
trade_server_test.cpp:21:6: error: ‘application’ was not declared in this scope
     (application, storeFactory, settings, logFactory /*optional*/);

I then modified the object name from "MyApplication" to "Application", and received the following error outputs. The "Application" class is defined in the header file Application.h. The compiler recognizes all of the included header files, so I am confused as to why it is saying "Application" is not declared in this scope.

trade_server_test.cpp: In function ‘int main(int, char**)’:
trade_server_test.cpp:17:3: error: ‘Application’ was not declared in this scope
   Application application;
   ^~~~~~~~~~~
trade_server_test.cpp:17:3: note: suggested alternative:
In file included from /usr/local/include/quickfix/Acceptor.h:29:0,
                 from /usr/local/include/quickfix/SocketAcceptor.h:29,
                 from trade_server_test.cpp:3:
/usr/local/include/quickfix/Application.h:43:7: note:   ‘FIX::Application’
 class Application
       ^~~~~~~~~~~
trade_server_test.cpp:21:6: error: ‘application’ was not declared in this scope
     (application, storeFactory, settings, logFactory /*optional*/);
      ^~~~~~~~~~~

Changing the object again from "Application"to "FIX::NullApplication" gets rid of the above errors, but then a new error appears:

/usr/bin/ld: cannot find -lxml2
collect2: error: ld returned 1 exit status

I have successfully downloaded and built QuickFix 1.15.1 on Ubuntu 18.04.2 LTS and have been able to run some of the example applications e.g. OrderMatch and TradeClient (although with only partial functionality) by following this procedure:

% tar xvzf quickfix-1.15.1.tar.gz
% cd quickfix
% ./bootstrap
% ./configure
% make
% sudo make install

Summary Questions

  1. How can I successfully compile the sample Acceptor program on Ubuntu 18.04.2 LTS for QuickFix 1.15.1? A step-by-step guide would be highly appreciated in terms of which libraries to link, header files to compile with which flags etc.
  2. Does the command for compilation seem correct?
  3. Should any of the header files be compiled alongside this application (although I thought these would have been compiled when make was ran during the building process?
Questioner
p.luck
Viewed
3
Botje 2020-07-31 16:33

You need to provide a subclass of Application yourself.
Let us look at the declaration of Application:

namespace FIX
{
  class Application
  {
  public:
    virtual ~Application() {};
    virtual void onCreate( const SessionID& ) = 0;
    virtual void onLogon( const SessionID& ) = 0;
    virtual void onLogout( const SessionID& ) = 0;
    virtual void toAdmin( Message&, const SessionID& ) = 0;
    virtual void toApp( Message&, const SessionID& )
      throw( DoNotSend ) = 0;
    virtual void fromAdmin( const Message&, const SessionID& )
      throw( FieldNotFound, IncorrectDataFormat, IncorrectTagValue, RejectLogon ) = 0;
    virtual void fromApp( const Message&, const SessionID& )
      throw( FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType ) = 0;
  };
}

All these methods marked with = 0 are pure virtual functions: they have no implementation and you cannot instantiate FIX::Application directly. Instead you have to declare a subclass. Where you do this does not matter, as long as the declaration is in scope at the moment you create your MyApplication instance. This can be either in the same file or in a header file you included.

A simple subclass of Application that does nothing might look like the following:

class MyApplication : public FIX::Application
{
  void onCreate( const SessionID& ) { std::cout << "onCreate" << std::endl; }
  void onLogon( const SessionID& ) { std::cout << "onLogon" << std::endl; }
  void onLogout( const SessionID& ) { std::cout << "onLogout" << std::endl; }
  void toAdmin( Message&, const SessionID& ) { std::cout << "toAdmin" << std::endl; }
  void toApp( Message&, const SessionID& ) throw( DoNotSend ) { std::cout << "toApp" << std::endl; }
  void fromAdmin( const Message&, const SessionID& ) throw( FieldNotFound, IncorrectDataFormat, IncorrectTagValue, RejectLogon ) { std::cout << "fromAdmin" << std::endl; }
  void fromApp( const Message&, const SessionID& ) throw( FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType ) { std::cout << "fromApp" << std::endl; }
};