Ошибки компоновщика сборки CMake при включении службы ADTF в фильтр ADTF

Я получаю странные ошибки компоновщика, которые я не понимаю. Я создал прослушиватель сигналов ADTF, слегка адаптировав исходный код демонстрационной версии: https://support.digitalwerk.net/adtf/v3/adtf_html/page_demo_signal_listener_code.html (для работы кода требовались некоторые #includes). Я создал этот CMakeLists.txt на основе руководства ADTF (https://support.digitalwerk.net/adtf/v3/guides/tutorial_filter_signal.html):

      project(ExampleSignalListener
    VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
)

adtf_add_system_service(${PROJECT_NAME}
    cExampleSignalListener.h
    cExampleSignalListener.cpp
)

find_package(ADTF REQUIRED COMPONENTS systemsdk)
find_package(ADTF REQUIRED COMPONENTS base)
find_package(ADTF REQUIRED COMPONENTS ucom3)

target_include_directories(${PROJECT_NAME} PUBLIC
   $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
)

adtf_install_target(${PROJECT_NAME}
    toolbox/bin
)

adtf_create_plugindescription(
    TARGET
        ${PROJECT_NAME}
    PLUGIN_SUBDIR
        toolbox/bin
)

Проект exampleSignalListener строится (в VS2022) и работает в ADTF, как и ожидалось (регистрирует значения сигналов из реестра сигналов на консоли). Теперь я хочу использовать значения этого сигнала в другом фильтре. Я думал, что лучше всего использовать #include <cExampleSignalListener.h>. Здесь возникла первая проблема: по какой-то причине компоновщик другого проекта искал exampleSignalListener.adtfplugin вместо файла .lib:

      ..\Example_Signal_Listener\Release\ExampleSignalListener.adtfplugin : fatal error LNK1107: invalid or corrupt file: cannot read at 0x308

Я мог бы это исправить, перейдя в «Свойства» > «Компоновщик» > «Ввод» > «Дополнительные зависимости» и вручную изменив .adtfplugin на .lib. Я упоминаю об этом, потому что предполагаю, что это странное поведение связано с моим CMakeLists.txt, и я хотел бы это исправить. Также я могу себе представить, что это актуально для моей текущей, еще нерешенной проблемы:

При связывании .lib и включении заголовка теперь создается новая ошибка, как только я пытаюсь добавить cExampleSignalListener в качестве переменной-члена:

      cExampleSignalProvider.obj : error LNK2019: unresolved external symbol "public: __cdecl cExampleSignalListener::cExampleSignalListener(void)" (??0cExampleSignalListener@@QEAA@XZ) referenced in function "public: __cdecl cExampleSignalProvider::cExampleSignalProvider(void)" (??0cExampleSignalProvider@@QEAA@XZ)
Example_Signal_Provider\Release\ExampleSignalProvider.adtfplugin : fatal error LNK1120: 1 unresolved externals

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

Дополнительный код, если это поможет решить проблему: cExampleSignalListener.h:

      #pragma once

#include <plugins/signal_listening_intf.h>
#include <adtfsystemsdk/adtf_service.h>
#include <adtfbase/adtf_plugin.h>
#include <adtfbase/adtf_runtime.h>

class cSignalDumper : public adtf::services::ant::ISignalListening::ISignalListener
{
public:
    cSignalDumper(const char* strSignalName);
public:
    void SignalUpdated(adtf::services::ant::ISignalRegistry::tSignalID nSignalID, const adtf::services::ant::ISignalRegistry::tSignalValue& sValue) override;


private:
    A_UTILS_NS::cString m_strSignalName;
};
class cExampleSignalListener : public  adtf::system::ant::cADTFService, public adtf::services::ant::ISignalListening::ISignalsListener
{
public:
    ADTF_CLASS_ID_NAME(cExampleSignalListener, "example_signal_listener.service.adtf.cid", "Example Signal Listener");

    ADTF_CLASS_DEPENDENCIES(
        REQUIRE_INTERFACE(adtf::services::ISignalListening),
        PROVIDE_INTERFACE(adtf::services::ISignalListening)
    );

    cExampleSignalListener();

public: // overrides cService
    virtual tResult ServiceInit() override;
    virtual tResult ServiceShutdown() override;

public: // overrides ISignalListening::ISignalsListener
    virtual void SignalAdded(const adtf::services::ant::ISignalRegistry::tSignalAttributes& sSignalAttributes) override;
    virtual void SignalRemoved(const adtf::services::ant::ISignalRegistry::tSignalAttributes& sSignalAttributes) override;

private:
    adtf::ucom::ant::object_ptr<adtf::services::ant::ISignalListening> m_pSignalListening;
    std::unordered_map<adtf::services::ISignalRegistry::tSignalID, std::unique_ptr<cSignalDumper>> m_oDumper;
};

cExampleSignalProvider.h (файл, содержащий прослушиватель сигналов):

      /**
 *
 * ADTF Tutorial filter for data processing
 *
 */
#pragma once

 // Include all necessary headers from the ADTF SDK
#include <adtffiltersdk/adtf_filtersdk.h>
#include <plugins/signal_registry_intf.h>
#include <cExampleSignalListener.h>

#include <adtffiltersdk/filter.h>
#include <adtfsystemsdk/kernel_timer.h>
#include <adtf_mediadescription.h>
#include <adtf_devicetb_sdk.h>

#include <mutex>
#include <unordered_set>

// For simplicity use the necessary namespaces
using namespace adtf::util;
using namespace adtf::ucom;
using namespace adtf::base;
using namespace adtf::streaming;
using namespace adtf::mediadescription;
using namespace adtf::filter;
using namespace adtf::services;

// Now we declare a new class cExampleSignalProvider that
// inherits from cFilter. This will be our Tutorial Filter.
// We also implement IEnabledSignals to react to signal requests.
class cExampleSignalProvider final :
    public cFilter,
    public ISignalRegistry::ISignalProvider::IEnabledSignals
{
public:
    // Inside the class declaration we use an ADTF macro to enable correct treatment
    // of class identifier and class name by IClassInfo and the class factories.
    ADTF_CLASS_ID_NAME(cExampleSignalProvider,
        "ExampleSignalProvider.filter.adtf_guides.cid",
        "Example Signal Provider");

    // Inform the tools that we require an service that provides the Signal Registry interface.
    ADTF_CLASS_DEPENDENCIES(REQUIRE_INTERFACE(adtf::services::ISignalRegistry));

public:
    // We implement the constructor where we create our Pins.
    cExampleSignalProvider();

    // We override the Init method in order to access the Signal Registry Service
    // And our instance name.
    tResult Init(tInitStage eStage) override;

    // We override the ProcessInput method, that we configure to be called each time a trigger occures via one input Pin.
    tResult ProcessInput(ISampleReader* pReader,
        const iobject_ptr<const ISample>& pSample) override;

    // this is called when the first consumer requests a signal to be generated.
    tResult EnableSignal(ISignalRegistry::tSignalID nSignalID) override;

    // this is called when the last consumer cancels its requests for a signal to be generated.
    tResult DisableSignal(ISignalRegistry::tSignalID nSignalID) override;

private:
    // Reader to read data samples from our input Pin.
    ISampleReader* m_out;

    // this guards concurrent access to m_oEnabledSignals
    std::mutex m_oEnabledSignalMutex;

    // this store the ids of all requested signals
    std::unordered_set<ISignalRegistry::tSignalID> m_oEnabledSignals;

    // pointer to our Signal Provider instance.
    // must be the first member to destroy.
    // every method on this class can still be called until m_pProvider has completed destruction!!!
    object_ptr<ISignalRegistry::ISignalProvider> m_pProvider;

    // Here the error occurs when adding my cExampleSignalListener
    cExampleSignalListener m_signalListener;
};

CMakeLists.txt для exampleSignalProvider:

      project(ExampleSignalProvider
    VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
    )

adtf_add_filter(${PROJECT_NAME}
    cExampleSignalProvider.h
    cExampleSignalProvider.cpp
    )

target_include_directories(${PROJECT_NAME}
        PUBLIC
           ${CMAKE_CURRENT_SOURCE_DIR}
    )

find_package(ADTF COMPONENTS filtersdk REQUIRED)
find_package(ADTF COMPONENTS systemsdk REQUIRED)

target_link_libraries(${PROJECT_NAME}
        PUBLIC
            ExampleSignalListener
    )

adtf_install_target(${PROJECT_NAME}
        toolbox/bin
    )

adtf_create_plugindescription(
        TARGET
           ${PROJECT_NAME}
        PLUGIN_SUBDIR
            toolbox/bin
   )

0 ответов

Другие вопросы по тегам