ADTF服务集成至过滤器时CMake构建链接错误排查
ADTF项目链接错误问题
背景
基于ADTF官方示例修改实现了ExampleSignalListener系统服务,项目在VS2022中构建正常,且能在ADTF中正常运行(将信号注册表的信号值输出至控制台)。现在需要在另一个过滤器ExampleSignalProvider中复用该服务的功能,遇到两处链接错误。
问题1:链接器尝试加载.adtfplugin而非.lib文件
错误信息
..\Example_Signal_Listener\Release\ExampleSignalListener.adtfplugin : fatal error LNK1107: invalid or corrupt file: cannot read at 0x308
临时解决方式
手动修改项目属性>链接器>输入>附加依赖项,将.adtfplugin替换为.lib文件可暂时解决,但希望通过修正CMakeLists.txt从根源解决问题。
ExampleSignalListener的CMake配置
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 )
问题2:添加成员变量后出现未解析外部符号
错误信息
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
现象说明
链接.lib文件并包含头文件后,空项目构建正常,但一旦在cExampleSignalProvider中添加cExampleSignalListener作为成员变量,就触发上述错误。即使将实现直接写入头文件,也会报其他头文件函数未解析的错误。
相关代码文件
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; };
ExampleSignalProvider的CMake配置
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 )
内容的提问来源于stack exchange,提问作者Dennix
相关产品推荐
相关产品推荐

