QuickFix C++: ошибки при компиляции Acceptor

Цель:

Собрать программу Acceptor (сервер). Когда это будет завершено, затем скомпилируйте инициатор (клиент), чтобы затем распечатать простой вывод, чтобы подтвердить, что два приложения взаимодействуют друг с другом (требования, которые я прочитал в документации QuickFix и в основном понимаю).

Обратите внимание перед публикацией этого вопроса, что мы проконсультировались со списком рассылки QuickFix и SO. Вопрос с похожими проблемами можно найти по следующему URL-адресу, однако ответы по-прежнему вызывают у меня некоторую путаницу: Компиляция программы быстрого исправления

Проблема:

При попытке скомпилировать следующий образец программы Acceptor, точно скопированный с http://www.quickfixengine.org/quickfix/doc/html/application.html, появлялись различные ошибки, как показано ниже. Команда компиляции, которую я использовал, была:

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

Программа:

#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;
    }
}

Выходы ошибок

Наблюдаются следующие ошибки:

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*/);

Затем я изменил имя объекта с "MyApplication" на "Application" и получил следующие выходные данные об ошибках. Класс приложения определен в заголовочном файле Application.h. Компилятор распознает все включенные файлы заголовков, поэтому я не понимаю, почему он говорит, что приложение не объявлено в этой области.

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*/);
      ^~~~~~~~~~~

Изменение объекта снова с "Application" на "FIX::NullApplication" избавляет от вышеуказанных ошибок, но затем появляется новая ошибка:

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

Я успешно загрузил и собрал QuickFix 1.15.1 на Ubuntu 18.04.2 LTS и смог запустить некоторые примеры приложений, например. OrderMatch и TradeClient (хотя и с частичной функциональностью), выполнив следующую процедуру:

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

Сводные вопросы

  1. Как мне успешно скомпилировать пример программы Acceptor на Ubuntu 18.04.2 LTS для QuickFix 1.15.1? Пошаговое руководство будет высоко оценено с точки зрения того, какие библиотеки связать, заголовочные файлы для компиляции с какими флагами и т. д.
  2. Команда для компиляции кажется правильной?
  3. Должен ли какой-либо из файлов заголовков компилироваться вместе с этим приложением (хотя я думал, что они были скомпилированы, когда make запускался во время процесса building?

person p.luck    schedule 29.07.2020    source источник
comment
Для устранения ошибки xml2 вам необходимо установить пакет libxml2-dev или аналогичный в вашем дистрибутиве.   -  person Botje    schedule 29.07.2020
comment
Пример кода действительно показывает вам, как подключить пользовательский подкласс FIX::Application, вы должны создать этот подкласс.   -  person Botje    schedule 29.07.2020
comment
Что касается вашего третьего вопроса: никакие заголовочные файлы не должны компилироваться отдельно. Они включаются при компиляции файлов cpp.   -  person Botje    schedule 29.07.2020
comment
(эти комментарии действительно должны быть ответом, извините)   -  person Botje    schedule 29.07.2020
comment
Привет @Botje, спасибо за вашу помощь и никаких проблем с комментариями. Не могли бы вы уточнить свой комментарий относительно создания подкласса? Из документации кажется, что класс/подкласс уже создан в quickfix/application.h... мне нужно создать новый файл заголовка? Извините, если моя формулировка неточна, я застрял на этом вопросе в течение некоторого времени.   -  person p.luck    schedule 29.07.2020
comment
Да, абстрактный класс приложения объявлен в этом заголовке. Вам нужно предоставить конкретную реализацию, такую ​​как NullApplication, которую вы нашли. Если эти понятия не знакомы, найдите время, чтобы прочитать хороший учебник C++ OO.   -  person Botje    schedule 31.07.2020


Ответы (1)


Вам нужно предоставить подкласс Application самостоятельно.
Давайте посмотрим на объявление 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;
  };
}

Все эти методы, помеченные = 0, являются чисто виртуальными функциями: у них нет реализации, и вы не можете напрямую создавать экземпляры FIX::Application. Вместо этого вы должны объявить подкласс. Где вы это делаете, не имеет значения, если объявление находится в области действия в момент создания экземпляра MyApplication. Это может быть либо в том же файле, либо в заголовочном файле, который вы включили.

Простой подкласс Application, который ничего не делает, может выглядеть следующим образом:

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; }
};
person Botje    schedule 31.07.2020
comment
Я очень ценю подробный ответ, это полностью решило мою проблему. Спасибо, что нашли время, чтобы предоставить такое хорошо структурированное объяснение - теперь все работает, как ожидалось. - person p.luck; 04.08.2020