提问人:Dennix 提问时间:6/6/2023 最后编辑:Dennix 更新时间:6/6/2023 访问量:34
在 ADTF 筛选器中包含 ADTF 服务时出现 CMake 生成链接器错误
CMake build linker errors when including an ADTF service in an ADTF filter
问:
我遇到了我不明白的奇怪的链接器错误。 我通过稍微调整演示版本的源代码来创建一个 ADTF 信号侦听器:https://support.digitalwerk.net/adtf/v3/adtf_html/page_demo_signal_listener_code.html(代码需要一些 #includes 才能实际工作)。 我根据 ADTF 教程 (https://support.digitalwerk.net/adtf/v3/guides/tutorial_filter_signal.html) 创建了这个 CMakeLists.txt:
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 for 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
)
答: 暂无答案
评论
find_package(ADTF)
find_package
project()
project()
adtf_add_system_service
find_package(ADTF)
find_package(ADTF)