ecFlow学习笔记04:使用C++ API

目录

ecFlow提供命令行和Python API两种方式交互方式,命令行适合加载、替换、删除系统等操作,Python API适合进行二次开发。但Python API的局限在于必须编译ecFlow源码才能得到ecFlow的Python包,不支持pip等包安装器,部署二次开发的应用非常繁琐。

为了封装ecFlow的Python API,我开发了ecflow-docker,构建Docker镜像时编译ecFlow源码。

既然ecFlow使用Boost Python封装Python接口,我们可以直接使用c++ API与ecFlow交互。虽然这不是官方推荐的方式,但使用c++接口二次开发的应用更方便部署(使用静态链接库,直接拷贝二进制程序)。下面介绍如何使用ecFlow的c++ API。

概述

ecFlow客户端中使用ClientInvoker与ecFlow服务通讯,使用Defs描述整个服务的节点树。

调用ClientInvokersync_local方法,可以获取节点树的当前状态。

链接

使用cmake编译ecFlow后,会有两个目录:

  • ECFLOW_SOURCE_DIR:ecFlow源码目录
  • ECFLOW_BUILD_DIR:ecFlow编译目录,包含生成的静态库文件

为了调用ecFlow的c++ API,需要设置头文件包含路径和连接库。下面的代码构造ecFlow的cmake接口库目标,为其他构建目标提供头文件路径和链接库。

if(NOT ECFLOW_BUILD_DIR OR NOT ECFLOW_SOURCE_DIR)
    message(FATAL_ERROR "Please set ECFLOW_BUILD_DIR and ECFLOW_SOURCE_DIR")
endif()

add_library(Ecflow INTERFACE)

target_include_directories(Ecflow INTERFACE
    ${ECFLOW_SOURCE_DIR}/ACore/src
    ${ECFLOW_SOURCE_DIR}/ANattr/src
    ${ECFLOW_SOURCE_DIR}/ANode/src
    ${ECFLOW_SOURCE_DIR}/Base/src
    ${ECFLOW_SOURCE_DIR}/Base/src/cts
    ${ECFLOW_SOURCE_DIR}/Base/src/stc
    ${ECFLOW_SOURCE_DIR}/CSim/src
    ${ECFLOW_SOURCE_DIR}/Client/src
)

target_link_libraries(Ecflow INTERFACE
    ${ECFLOW_BUILD_DIR}/Client/liblibclient.a
    ${ECFLOW_BUILD_DIR}/Base/libbase.a
    ${ECFLOW_BUILD_DIR}/CSim/liblibsimu.a
    ${ECFLOW_BUILD_DIR}/ANode/libnode.a
    ${ECFLOW_BUILD_DIR}/ANattr/libnodeattr.a
    ${ECFLOW_BUILD_DIR}/ACore/libcore.a
    )

add_library(Ecflow::Ecflow ALIAS Ecflow)

其他构建目标需要链接该接口,同时需要链接Boost库。例如:

add_library(ecflow_util STATIC)

target_sources(ecflow_util PRIVATE
    src/ecflow_client.cpp)

target_include_directories(ecflow_util
    PUBLIC
        $<INSTALL_INTERFACE:include>
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    )

target_link_libraries(ecflow_util
    PUBLIC
        workflow_model
    PRIVATE
        Ecflow::Ecflow
    INTERFACE
        Boost::system
        Boost::filesystem
        Boost::date_time
        Boost::program_options
        Boost::serialization
        Boost::thread
        Boost::regex
    )

接口

使用下面的代码,可以获取ecFlow所有节点的运行状态:

#include <ClientInvoker.hpp>
#include <Defs.hpp>

ClientInvoker invoker_;
defs_ptr defs_;

invoker_.set_host_port("some host", "some port");
auto sync_result = invoker_.sync_local();
defs_ = invoker_.defs();

std::vector<node_ptr> nodes;
defs_->get_all_nodes(nodes);

for(auto &node: nodes) {
    string node_path = node->absNodePath();
    string status = DState::toString(node->dstate());
}

参考

perillaroc/ecflow-client-cpp