# celix **Repository Path**: mirrors/celix ## Basic Information - **Project Name**: celix - **Description**: Apache Celix 是一个使用 C 和 C++ 实现的 OSGi 规范的项目 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: https://www.oschina.net/p/apache-celix - **GVP Project**: No ## Statistics - **Stars**: 4 - **Forks**: 2 - **Created**: 2020-06-23 - **Last Updated**: 2025-12-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Apache Celix [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) ![Celix Ubuntu](https://github.com/apache/celix/workflows/Celix%20Ubuntu/badge.svg) ![Celix MacOS](https://github.com/apache/celix/workflows/Celix%20MacOS/badge.svg) [![codecov](https://codecov.io/gh/apache/celix/branch/master/graph/badge.svg)](https://codecov.io/gh/apache/celix) [![Coverity Scan Build Status](https://scan.coverity.com/projects/6685/badge.svg)](https://scan.coverity.com/projects/6685) [![Open in Dev Containers](https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue&logo=visualstudiocode)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/apache/celix) Apache Celix is a framework for C and C++14 to develop dynamic modular software applications using component and in-process service-oriented programming. Apache Celix is inspired by the [OSGi specification](https://www.osgi.org/) adapted for C and C++. ## Documentation - [Building Apache Celix](documents/building/README.md) - [Apache Celix Intro](documents/README.md) ## C++ Usage ### Hello World Bundle Modularity in Celix is achieved by runtime installable bundles and dynamic - in process - services. A Celix bundle is set of resources packed in a zip containing at least a manifest and almost always some shared library containing the bundle functionality. A Celix bundle can be created using the Celix CMake function `add_celix_bundle`. A Celix bundle is activated by executing the bundle entry points. For C++ bundles these bundle entry points are generated using the `CELIX_GEN_CXX_BUNDLE_ACTIVATOR` macro. Celix applications (Celix containers) can be created with the Celix CMake function `add_celix_container`. This function generates a C++ main function and is also used to configure default installed bundles. This can be bundles provided by Celix, an other project or build by the project self. ```C++ //src/MyBundleActivator.cc #include #include "celix/BundleActivator.h" class MyBundleActivator { public: explicit MyBundleActivator(const std::shared_ptr& ctx) { std::cout << "Hello world from bundle with id " << ctx->getBundleId() << std::endl; } ~MyBundleActivator() noexcept { std::cout << "Goodbye world" << std::endl; } }; CELIX_GEN_CXX_BUNDLE_ACTIVATOR(MyBundleActivator) ``` ```CMake #CMakeLists.txt find_package(Celix REQUIRED) add_celix_bundle(MyBundle SOURCES src/MyBundleActivator.cc ) add_celix_container(MyContainer BUNDLES Celix::ShellCxx Celix::shell_tui MyBundle ) ``` ```sh #bash #goto project dir cd cmake-build-debug #assuming clion cmake-build-debug dir cd deploy/MyContainer ./MyContainer #Celix shell -> lb -a #list of all installed bundles -> help #list of all available Celix shell commands -> help celix::lb #Help info about the shell command `celix::lb` -> stop 3 #stops MyBundle -> start 3 #starts MyBundle -> stop 0 #stops the Celix framework ``` ### Register a service In the Celix framework, a service is a C++ object or C struct registered in the Celix framework service registry under one interface together with properties (meta information). Services can be discovered and used by bundles. ```C++ //include/ICalc.h #pragma once class ICalc { public: virtual ~ICalc() noexcept = default; virtual int add(int a, int b) = 0; }; ``` ```C++ //src/CalcProviderBundleActivator.cc #include "ICalc.h" #include "celix/BundleActivator.h" class CalcProvider : public ICalc { public: ~CalcProvider() noexcept override = default; int add(int a, int b) override { return a + b; } }; class CalcProviderBundleActivator { public: explicit CalcProviderBundleActivator(const std::shared_ptr& ctx) { reg = ctx->registerService(std::make_shared()) .build(); } private: std::shared_ptr reg{}; }; CELIX_GEN_CXX_BUNDLE_ACTIVATOR(CalcProviderBundleActivator) ``` ```CMake #CMakeLists.txt find_package(Celix REQUIRED) add_celix_bundle(CalcProviderBundle SOURCES src/CalcProviderBundleActivator.cc ) target_include_directories(CalcProviderBundle PRIVATE include) add_celix_container(CalcProviderContainer BUNDLES Celix::ShellCxx Celix::shell_tui CalcProviderBundle ) ``` ```bash #bash #goto project dir cd cmake-build-debug #assuming clion cmake-build-debug dir cd deploy/CalcProviderBundle ./CalcProviderBundle ``` ### Use a service (ad hoc) ```C++ //include/ICalc.h #pragma once class ICalc { public: virtual ~ICalc() noexcept = default; virtual int add(int a, int b) = 0; }; ``` ```C++ //src/CalcUserBundleActivator.cc #include #include "ICalc.h" #include "celix/BundleActivator.h" class CalcUserBundleActivator { public: explicit CalcUserBundleActivator(const std::shared_ptr& ctx) { ctx->useService() .addUseCallback([](ICalc& calc) { std::cout << "result is " << calc.add(2, 3) << std::endl; }) .setTimeout(std::chrono::seconds{1}) //wait for 1 second if a service is not directly found .build(); } }; CELIX_GEN_CXX_BUNDLE_ACTIVATOR(CalcUserBundleActivator) ``` ```CMake #CMakeLists.txt find_package(Celix REQUIRED) add_celix_bundle(CalcUserBundle SOURCES src/CalcUserBundleActivator.cc ) target_include_directories(CalcUserBundle PRIVATE include) add_celix_container(CalcUserContainer BUNDLES Celix::ShellCxx Celix::shell_tui CalcProviderBundle CalcUserBundle ) ``` ```bash #bash #goto project dir cd cmake-build-debug #assuming clion cmake-build-debug dir cd deploy/CalcUserContainer ./CalcUserContainer ``` ### Track services ```C++ //include/ICalc.h #pragma once class ICalc { public: virtual ~ICalc() noexcept = default; virtual int add(int a, int b) = 0; }; ``` ```C++ //src/CalcTrackerBundleActivator.cc #include #include "ICalc.h" #include "celix/BundleActivator.h" class CalcTrackerBundleActivator { public: explicit CalcTrackerBundleActivator(const std::shared_ptr& ctx) { tracker = ctx->trackServices() .build(); for (auto& calc : tracker->getServices()) { std::cout << "result is " << std::to_string(calc->add(2, 3)) << std::endl; } } private: std::shared_ptr> tracker{}; }; CELIX_GEN_CXX_BUNDLE_ACTIVATOR(CalcTrackerBundleActivator) ``` ```CMake find_package(Celix REQUIRED) add_celix_bundle(CalcTrackerBundle SOURCES src/CalcTrackerBundleActivator.cc ) target_include_directories(CalcTrackerBundle PRIVATE include) add_celix_container(CalcTrackerContainer BUNDLES Celix::ShellCxx Celix::shell_tui CalcProviderBundle CalcTrackerBundle ) ``` ```bash #bash #goto project dir cd cmake-build-debug #assuming clion cmake-build-debug dir cd deploy/CalcTrackerContainer ./CalcTrackerContainer ``` ### Service properties and filters ```C++ //src/FilterExampleBundleActivator.cc #include #include "celix/BundleActivator.h" #include "celix/IShellCommand.h" class HelloWorldShellCommand : public celix::IShellCommand { public: void executeCommand(const std::string& /*commandLine*/, const std::vector& /*commandArgs*/, FILE* outStream, FILE* /*errorStream*/) { fprintf(outStream, "Hello World\n"); } }; class FilterExampleBundleActivator { public: explicit FilterExampleBundleActivator(const std::shared_ptr& ctx) { auto reg1 = ctx->registerService(std::make_shared()) .addProperty(celix::IShellCommand::COMMAND_NAME, "command1") .build(); auto reg2 = ctx->registerService(std::make_shared()) .addProperty(celix::IShellCommand::COMMAND_NAME, "command2") .build(); regs.push_back(reg1); regs.push_back(reg2); auto serviceIdsNoFilter = ctx->findServices(); auto serviceIdsWithFilter = ctx->findServices(std::string{"("} + celix::IShellCommand::COMMAND_NAME + "=" + "command1)"); std::cout << "Found " << std::to_string(serviceIdsNoFilter.size()) << " IShelLCommand services and found "; std::cout << std::to_string(serviceIdsWithFilter.size()) << " IShellCommand service with name command1" << std::endl; } private: std::vector> regs{}; }; CELIX_GEN_CXX_BUNDLE_ACTIVATOR(FilterExampleBundleActivator) ``` ```CMake #CMakeLists.txt find_package(Celix REQUIRED) add_celix_bundle(FilterExampleBundle SOURCES src/FilterExampleBundleActivator.cc ) target_link_libraries(FilterExampleBundle PRIVATE Celix::shell_api) #adds celix/IShellCommand.h to the include path add_celix_container(FilterExampleContainer BUNDLES Celix::ShellCxx Celix::shell_tui FilterExampleBundle ) ``` ```bash #bash #goto project dir cd cmake-build-debug #assuming clion cmake-build-debug dir cd deploy/FilterExampleContainer ./FilterExampleContainer #Celix shell -> command1 -> command2 -> help ```