You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2018/05/08 19:34:28 UTC

[4/4] celix git commit: CELIX-426; Refactoring for update C bundle context api and ads some C++ examples

CELIX-426; Refactoring for update C bundle context api and ads some C++ examples


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/7df4d26d
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/7df4d26d
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/7df4d26d

Branch: refs/heads/feature/CELIX-426-cxx-api
Commit: 7df4d26d984e3ed223ee30ff36de3a567ade45f4
Parents: 37217c2
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Tue May 8 21:33:51 2018 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Tue May 8 21:33:51 2018 +0200

----------------------------------------------------------------------
 diff.tmp                                        | 1166 ++++++++++++++++++
 examples/celix-examples/CMakeLists.txt          |    4 +-
 .../best_practice_example_cxx/CMakeLists.txt    |   62 +
 .../api/IAnotherExample.h                       |   34 +
 .../best_practice_example_cxx/api/example.h     |   43 +
 .../best_practice_example_cxx/bar/Bar.cc        |   48 +
 .../best_practice_example_cxx/bar/Bar.h         |   40 +
 .../bar/BarActivator.cc                         |   49 +
 .../bar/BarActivator.h                          |   34 +
 .../best_practice_example_cxx/baz/Baz.cc        |   84 ++
 .../best_practice_example_cxx/baz/Baz.h         |   54 +
 .../baz/BazActivator.cc                         |   45 +
 .../baz/BazActivator.h                          |   31 +
 .../best_practice_example_cxx/foo/Foo.cc        |   60 +
 .../best_practice_example_cxx/foo/Foo.h         |   48 +
 .../foo/FooActivator.cc                         |   43 +
 .../foo/FooActivator.h                          |   32 +
 .../bundle_example_cxx/src/BundleActivator.cc   |    9 +-
 .../services_example_cxx/CMakeLists.txt         |   48 +-
 .../services_example_cxx/api/IAnotherExample.h  |   34 -
 .../services_example_cxx/api/ICalc.h            |   37 +
 .../services_example_cxx/api/calc.h             |   43 +
 .../services_example_cxx/api/example.h          |   43 -
 .../services_example_cxx/bar/CMakeLists.txt     |   41 -
 .../bar/private/include/Bar.h                   |   40 -
 .../bar/private/include/BarActivator.h          |   36 -
 .../services_example_cxx/bar/private/src/Bar.cc |   48 -
 .../bar/private/src/BarActivator.cc             |   48 -
 .../services_example_cxx/baz/CMakeLists.txt     |   41 -
 .../baz/private/include/Baz.h                   |   54 -
 .../baz/private/include/BazActivator.h          |   34 -
 .../services_example_cxx/baz/private/src/Baz.cc |   84 --
 .../baz/private/src/BazActivator.cc             |   45 -
 .../services_example_cxx/foo/CMakeLists.txt     |   41 -
 .../foo/private/include/Foo.h                   |   48 -
 .../foo/private/include/FooActivator.h          |   34 -
 .../services_example_cxx/foo/private/src/Foo.cc |   60 -
 .../foo/private/src/FooActivator.cc             |   43 -
 .../src/ConsumerBundleActivator.cc              |   72 ++
 .../src/ProviderBundleActivator.cc              |   98 ++
 framework/gtest/src/cxx_BundleContext_tests.cc  |   43 +-
 framework/include/celix/BundleContext.h         |   35 +-
 .../include/celix/impl/BundleContextImpl.h      |   68 +-
 43 files changed, 2224 insertions(+), 880 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/diff.tmp
----------------------------------------------------------------------
diff --git a/diff.tmp b/diff.tmp
new file mode 100644
index 0000000..f936290
--- /dev/null
+++ b/diff.tmp
@@ -0,0 +1,1166 @@
+diff --git a/examples/celix-examples/CMakeLists.txt b/examples/celix-examples/CMakeLists.txt
+index fd2ec1cb..bd700658 100644
+--- a/examples/celix-examples/CMakeLists.txt
++++ b/examples/celix-examples/CMakeLists.txt
+@@ -23,11 +23,13 @@ endif ()
+ if (EXAMPLES)
+     add_subdirectory(bundle_example_cxx)
+ 
++    add_subdirectory(services_example_cxx)
++
+     add_subdirectory(hello_world)
+     add_subdirectory(hello_world_test)
+ 
+     add_subdirectory(services_example_c)
+-    add_subdirectory(services_example_cxx)
++    add_subdirectory(best_practice_example_cxx)
+ 
+     add_subdirectory(dm_example)
+     add_subdirectory(dm_example_cxx)
+diff --git a/examples/celix-examples/best_practice_example_cxx/CMakeLists.txt b/examples/celix-examples/best_practice_example_cxx/CMakeLists.txt
+new file mode 100644
+index 00000000..faa7c002
+--- /dev/null
++++ b/examples/celix-examples/best_practice_example_cxx/CMakeLists.txt
+@@ -0,0 +1,62 @@
++# Licensed to the Apache Software Foundation (ASF) under one
++# or more contributor license agreements.  See the NOTICE file
++# distributed with this work for additional information
++# regarding copyright ownership.  The ASF licenses this file
++# to you under the Apache License, Version 2.0 (the
++# "License"); you may not use this file except in compliance
++# with the License.  You may obtain a copy of the License at
++#
++#   http://www.apache.org/licenses/LICENSE-2.0
++#
++# Unless required by applicable law or agreed to in writing,
++# software distributed under the License is distributed on an
++# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++# KIND, either express or implied.  See the License for the
++# specific language governing permissions and limitations
++# under the License.
++
++add_library(cxx_services_example_api INTERFACE)
++target_include_directories(cxx_services_example_api INTERFACE api)
++
++add_celix_bundle(cxx_foo
++        VERSION 1.0.0
++        SOURCES
++        foo/Foo.cc
++        foo/Foo.h
++        foo/FooActivator.cc
++        foo/FooActivator.h
++    )
++target_link_libraries(cxx_foo PRIVATE cxx_services_example_api)
++
++add_celix_bundle(cxx_bar
++        VERSION 1.0.0
++        SOURCES
++            bar/Bar.cc
++            bar/Bar.h
++            bar/BarActivator.cc
++            bar/BarActivator.h
++)
++target_link_libraries(cxx_bar PRIVATE cxx_services_example_api)
++
++add_celix_bundle(cxx_baz
++    VERSION 1.0.0
++    SOURCES
++        baz/Baz.cc
++        baz/Baz.h
++        baz/BazActivator.cc
++        baz/BazActivator.h
++)
++target_link_libraries(cxx_baz PRIVATE cxx_services_example_api)
++
++add_celix_container(best_practice_example_cxx
++    GROUP services_example
++    COPY
++    BUNDLES
++        Celix::shell
++        Celix::shell_tui
++        cxx_bar
++        cxx_foo
++        cxx_baz
++    PROPERTIES
++        example=value
++)
+diff --git a/examples/celix-examples/services_example_cxx/api/IAnotherExample.h b/examples/celix-examples/best_practice_example_cxx/api/IAnotherExample.h
+similarity index 87%
+rename from examples/celix-examples/services_example_cxx/api/IAnotherExample.h
+rename to examples/celix-examples/best_practice_example_cxx/api/IAnotherExample.h
+index 0cd6c225..2ed4d6dd 100644
+--- a/examples/celix-examples/services_example_cxx/api/IAnotherExample.h
++++ b/examples/celix-examples/best_practice_example_cxx/api/IAnotherExample.h
+@@ -20,14 +20,14 @@
+ #ifndef IANOTHER_EXAMPLE_H
+ #define IANOTHER_EXAMPLE_H
+ 
+-#define IANOTHER_EXAMPLE_VERSION "1.0.0"
+-#define IANOTHER_EXAMPLE_CONSUMER_RANGE "[1.0.0,2.0.0)"
+ 
+ class IAnotherExample {
+-protected:
+-    IAnotherExample() = default;
+-    virtual ~IAnotherExample() = default;
+ public:
++    static constexpr const char * const VERSION = "1.0.0";
++    static constexpr const char * const CONSUMER_RANGE = "[1.0.0,2.0.0)";
++
++    virtual ~IAnotherExample() = default;
++
+     virtual double method(int arg1, double arg2) = 0;
+ };
+ 
+diff --git a/examples/celix-examples/services_example_cxx/api/example.h b/examples/celix-examples/best_practice_example_cxx/api/example.h
+similarity index 100%
+rename from examples/celix-examples/services_example_cxx/api/example.h
+rename to examples/celix-examples/best_practice_example_cxx/api/example.h
+diff --git a/examples/celix-examples/services_example_cxx/bar/private/src/Bar.cc b/examples/celix-examples/best_practice_example_cxx/bar/Bar.cc
+similarity index 100%
+rename from examples/celix-examples/services_example_cxx/bar/private/src/Bar.cc
+rename to examples/celix-examples/best_practice_example_cxx/bar/Bar.cc
+diff --git a/examples/celix-examples/services_example_cxx/bar/private/include/Bar.h b/examples/celix-examples/best_practice_example_cxx/bar/Bar.h
+similarity index 100%
+rename from examples/celix-examples/services_example_cxx/bar/private/include/Bar.h
+rename to examples/celix-examples/best_practice_example_cxx/bar/Bar.h
+diff --git a/examples/celix-examples/services_example_cxx/bar/private/src/BarActivator.cc b/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.cc
+similarity index 83%
+rename from examples/celix-examples/services_example_cxx/bar/private/src/BarActivator.cc
+rename to examples/celix-examples/best_practice_example_cxx/bar/BarActivator.cc
+index e4b8becd..1dc5a7e4 100644
+--- a/examples/celix-examples/services_example_cxx/bar/private/src/BarActivator.cc
++++ b/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.cc
+@@ -20,13 +20,14 @@
+ #include "Bar.h"
+ #include "BarActivator.h"
+ 
+-using namespace celix::dm;
++#include "celix/BundleActivator.h"
+ 
+-DmActivator* DmActivator::create(DependencyManager& mng) {
+-    return new BarActivator(mng);
++celix::IBundleActivator* celix::createBundleActivator(celix::BundleContext &ctx) {
++    return new BarActivator{ctx};
+ }
+ 
+-void BarActivator::init() {
++BarActivator::BarActivator(celix::BundleContext& ctx) {
++    auto &mng = ctx.getDependencyManager();
+     auto bar = std::unique_ptr<Bar>{new Bar{}};
+ 
+     Properties props;
+@@ -42,7 +43,7 @@ void BarActivator::init() {
+     };
+ 
+     mng.createComponent(std::move(bar))  //using a pointer a instance. Also supported is lazy initialization (default constructor needed) or a rvalue reference (move)
+-        .addInterface<IAnotherExample>(IANOTHER_EXAMPLE_VERSION, props)
++        .addInterface<IAnotherExample>(IAnotherExample::VERSION, props)
+         .addCInterface(&this->cExample, EXAMPLE_NAME, EXAMPLE_VERSION, cProps)
+         .setCallbacks(&Bar::init, &Bar::start, &Bar::stop, &Bar::deinit);
+ }
+\ No newline at end of file
+diff --git a/examples/celix-examples/services_example_cxx/bar/private/include/BarActivator.h b/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.h
+similarity index 82%
+rename from examples/celix-examples/services_example_cxx/bar/private/include/BarActivator.h
+rename to examples/celix-examples/best_practice_example_cxx/bar/BarActivator.h
+index 0c635a83..8642c4f6 100644
+--- a/examples/celix-examples/services_example_cxx/bar/private/include/BarActivator.h
++++ b/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.h
+@@ -20,17 +20,15 @@
+ #ifndef BAR_ACTIVATOR_H
+ #define BAR_ACTIVATOR_H
+ 
+-#include "celix/dm/DmActivator.h"
++#include "celix/IBundleActivator.h"
+ #include "example.h"
+ 
+-using namespace celix::dm;
+-
+-class BarActivator : public DmActivator {
++class BarActivator : public celix::IBundleActivator {
++public:
++    BarActivator(celix::BundleContext &ctx);
++    virtual ~BarActivator() = default;
+ private:
+     example_t cExample {nullptr, nullptr};
+-public:
+-    BarActivator(DependencyManager& mng) : DmActivator(mng) {}
+-    virtual void init() override;
+ };
+ 
+ #endif //BAR_ACTIVATOR_H
+diff --git a/examples/celix-examples/services_example_cxx/baz/private/src/Baz.cc b/examples/celix-examples/best_practice_example_cxx/baz/Baz.cc
+similarity index 100%
+rename from examples/celix-examples/services_example_cxx/baz/private/src/Baz.cc
+rename to examples/celix-examples/best_practice_example_cxx/baz/Baz.cc
+diff --git a/examples/celix-examples/services_example_cxx/baz/private/include/Baz.h b/examples/celix-examples/best_practice_example_cxx/baz/Baz.h
+similarity index 100%
+rename from examples/celix-examples/services_example_cxx/baz/private/include/Baz.h
+rename to examples/celix-examples/best_practice_example_cxx/baz/Baz.h
+diff --git a/examples/celix-examples/services_example_cxx/baz/private/src/BazActivator.cc b/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.cc
+similarity index 82%
+rename from examples/celix-examples/services_example_cxx/baz/private/src/BazActivator.cc
+rename to examples/celix-examples/best_practice_example_cxx/baz/BazActivator.cc
+index 3f17b5ad..a3d3a4fa 100644
+--- a/examples/celix-examples/services_example_cxx/baz/private/src/BazActivator.cc
++++ b/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.cc
+@@ -20,21 +20,21 @@
+ #include "Baz.h"
+ #include "BazActivator.h"
+ 
+-using namespace celix::dm;
++#include "celix/BundleActivator.h"
+ 
+-DmActivator* DmActivator::create(DependencyManager& mng) {
+-    return new BazActivator(mng);
++celix::IBundleActivator* celix::createBundleActivator(celix::BundleContext &ctx) {
++    return new BazActivator{ctx};
+ }
+ 
+-void BazActivator::init() {
+-
++BazActivator::BazActivator(celix::BundleContext& ctx) {
++    auto &mng = ctx.getDependencyManager();
+     Component<Baz>& cmp = mng.createComponent<Baz>()
+         .setCallbacks(nullptr, &Baz::start, &Baz::stop, nullptr);
+ 
+     cmp.createServiceDependency<IAnotherExample>()
+             .setRequired(true)
+             .setStrategy(DependencyUpdateStrategy::locking)
+-            .setVersionRange(IANOTHER_EXAMPLE_CONSUMER_RANGE)
++            .setVersionRange(IAnotherExample::CONSUMER_RANGE)
+             .setCallbacks(&Baz::addAnotherExample, &Baz::removeAnotherExample);
+ 
+     cmp.createCServiceDependency<example_t>(EXAMPLE_NAME)
+diff --git a/examples/celix-examples/services_example_cxx/baz/private/include/BazActivator.h b/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.h
+similarity index 81%
+rename from examples/celix-examples/services_example_cxx/baz/private/include/BazActivator.h
+rename to examples/celix-examples/best_practice_example_cxx/baz/BazActivator.h
+index fe249184..e1a7c38a 100644
+--- a/examples/celix-examples/services_example_cxx/baz/private/include/BazActivator.h
++++ b/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.h
+@@ -20,15 +20,12 @@
+ #ifndef BAZ_ACTIVATOR_H
+ #define BAZ_ACTIVATOR_H
+ 
+-#include "celix/dm/DmActivator.h"
++#include "celix/IBundleActivator.h"
+ 
+-using namespace celix::dm;
+-
+-class BazActivator : public DmActivator {
+-private:
++class BazActivator : public celix::IBundleActivator {
+ public:
+-    BazActivator(DependencyManager& mng) : DmActivator(mng) {}
+-    virtual void init() override;
++    BazActivator(celix::BundleContext &ctx);
++    virtual ~BazActivator() = default;
+ };
+ 
+ #endif //BAZ_ACTIVATOR_H
+diff --git a/examples/celix-examples/services_example_cxx/foo/private/src/Foo.cc b/examples/celix-examples/best_practice_example_cxx/foo/Foo.cc
+similarity index 100%
+rename from examples/celix-examples/services_example_cxx/foo/private/src/Foo.cc
+rename to examples/celix-examples/best_practice_example_cxx/foo/Foo.cc
+diff --git a/examples/celix-examples/services_example_cxx/foo/private/include/Foo.h b/examples/celix-examples/best_practice_example_cxx/foo/Foo.h
+similarity index 100%
+rename from examples/celix-examples/services_example_cxx/foo/private/include/Foo.h
+rename to examples/celix-examples/best_practice_example_cxx/foo/Foo.h
+diff --git a/examples/celix-examples/services_example_cxx/foo/private/src/FooActivator.cc b/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.cc
+similarity index 80%
+rename from examples/celix-examples/services_example_cxx/foo/private/src/FooActivator.cc
+rename to examples/celix-examples/best_practice_example_cxx/foo/FooActivator.cc
+index fba10cec..719da165 100644
+--- a/examples/celix-examples/services_example_cxx/foo/private/src/FooActivator.cc
++++ b/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.cc
+@@ -20,20 +20,20 @@
+ #include "Foo.h"
+ #include "FooActivator.h"
+ 
+-using namespace celix::dm;
++#include "celix/BundleActivator.h"
+ 
+-DmActivator* DmActivator::create(DependencyManager& mng) {
+-    return new FooActivator(mng);
++celix::IBundleActivator* celix::createBundleActivator(celix::BundleContext &ctx) {
++    return new FooActivator{ctx};
+ }
+ 
+-void FooActivator::init() {
+-
++FooActivator::FooActivator(celix::BundleContext& ctx) {
++    auto &mng = ctx.getDependencyManager();
+     Component<Foo>& cmp = mng.createComponent<Foo>()
+         .setCallbacks(nullptr, &Foo::start, &Foo::stop, nullptr);
+ 
+     cmp.createServiceDependency<IAnotherExample>()
+             .setRequired(true)
+-            .setVersionRange(IANOTHER_EXAMPLE_CONSUMER_RANGE)
++            .setVersionRange(IAnotherExample::CONSUMER_RANGE)
+             .setCallbacks(&Foo::setAnotherExample);
+ 
+     cmp.createCServiceDependency<example_t>(EXAMPLE_NAME)
+diff --git a/examples/celix-examples/services_example_cxx/foo/private/include/FooActivator.h b/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.h
+similarity index 81%
+rename from examples/celix-examples/services_example_cxx/foo/private/include/FooActivator.h
+rename to examples/celix-examples/best_practice_example_cxx/foo/FooActivator.h
+index 2917cbd6..a79d3659 100644
+--- a/examples/celix-examples/services_example_cxx/foo/private/include/FooActivator.h
++++ b/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.h
+@@ -20,15 +20,13 @@
+ #ifndef FOO_ACTIVATOR_H
+ #define FOO_ACTIVATOR_H
+ 
+-#include "celix/dm/DmActivator.h"
++#include "celix/IBundleActivator.h"
+ 
+-using namespace celix::dm;
+-
+-class FooActivator : public DmActivator {
++class FooActivator : public celix::IBundleActivator {
+ private:
+ public:
+-    FooActivator(DependencyManager& mng) : DmActivator(mng) {}
+-    virtual void init() override;
++    FooActivator(celix::BundleContext &ctx);
++    virtual ~FooActivator() = default;
+ };
+ 
+ #endif //FOO_ACTIVATOR_H
+diff --git a/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc b/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc
+index 5687ff0e..367d1dcb 100644
+--- a/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc
++++ b/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc
+@@ -24,14 +24,15 @@
+ namespace {
+     class BundleActivator : public celix::IBundleActivator {
+     public:
+-        BundleActivator(celix::BundleContext &_ctx) : ctx{_ctx} {
+-            std::cout << "Hello world from C++ bundle with id " << ctx.getBundle().getBundleId() << std::endl;
++        BundleActivator(celix::BundleContext &) {
++            //std::cout << "Hello world from C++ bundle with id " << ctx.getBundle().getBundleId() << std::endl;
++            std::cout << "Hello world from C++ bundle " << std::endl;
+         }
+         virtual ~BundleActivator() {
+-            std::cout << "Goodbye world from C++ bundle with id " << ctx.getBundle().getBundleId() << std::endl;
++            //std::cout << "Goodbye world from C++ bundle with id " << ctx.getBundle().getBundleId() << std::endl;
+         }
+     protected:
+-        celix::BundleContext &ctx;
++        //celix::BundleContext &ctx;
+     };
+ }
+ 
+diff --git a/examples/celix-examples/services_example_cxx/CMakeLists.txt b/examples/celix-examples/services_example_cxx/CMakeLists.txt
+index ba132519..fabd48f5 100644
+--- a/examples/celix-examples/services_example_cxx/CMakeLists.txt
++++ b/examples/celix-examples/services_example_cxx/CMakeLists.txt
+@@ -5,39 +5,35 @@
+ # to you under the Apache License, Version 2.0 (the
+ # "License"); you may not use this file except in compliance
+ # with the License.  You may obtain a copy of the License at
+-#
++# 
+ #   http://www.apache.org/licenses/LICENSE-2.0
+-#
++# 
+ # Unless required by applicable law or agreed to in writing,
+ # software distributed under the License is distributed on an
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ # KIND, either express or implied.  See the License for the
+ # specific language governing permissions and limitations
+ # under the License.
+-if (BUILD_DEPENDENCY_MANAGER_CXX)
+-    include_directories(
+-            ${PROJECT_SOURCE_DIR}/dependency_manager/public/include
+-            ${PROJECT_SOURCE_DIR}/dependency_manager_cxx/include
+-            ${PROJECT_SOURCE_DIR}/utils/public/include
+-            api
+-    )
+ 
+-    add_subdirectory(bar)
+-    add_subdirectory(foo)
+-    add_subdirectory(baz)
++add_library(services_example_api_cxx INTERFACE)
++target_include_directories(services_example_api_cxx INTERFACE api)
+ 
+-    add_celix_container(services_example_cxx
+-        GROUP services_example
+-        COPY
+-        BUNDLES
+-            Celix::shell
+-            Celix::shell_tui
+-            dm_shell
+-            bar_cxx
+-            foo_cxx
+-            baz_cxx
+-        PROPERTIES
+-            example=value
+-    )
++add_celix_bundle(provider_example_cxx
++        VERSION 1.0.0
++        SOURCES src/ProviderBundleActivator.cc
++)
++target_link_libraries(provider_example_cxx PRIVATE services_example_api_cxx)
+ 
+-endif ()
++add_celix_bundle(consumer_example_cxx
++        VERSION 1.0.0
++        SOURCES src/ConsumerBundleActivator.cc
++)
++target_link_libraries(consumer_example_cxx PRIVATE services_example_api_cxx)
++
++add_celix_container(services_example_cxx
++    BUNDLES
++        Celix::shell
++        Celix::shell_tui
++        provider_example_cxx
++        consumer_example_cxx
++)
+\ No newline at end of file
+diff --git a/examples/celix-examples/services_example_cxx/api/ICalc.h b/examples/celix-examples/services_example_cxx/api/ICalc.h
+new file mode 100644
+index 00000000..4507d1ab
+--- /dev/null
++++ b/examples/celix-examples/services_example_cxx/api/ICalc.h
+@@ -0,0 +1,37 @@
++/**
++ *Licensed to the Apache Software Foundation (ASF) under one
++ *or more contributor license agreements.  See the NOTICE file
++ *distributed with this work for additional information
++ *regarding copyright ownership.  The ASF licenses this file
++ *to you under the Apache License, Version 2.0 (the
++ *"License"); you may not use this file except in compliance
++ *with the License.  You may obtain a copy of the License at
++ *
++ *  http://www.apache.org/licenses/LICENSE-2.0
++ *
++ *Unless required by applicable law or agreed to in writing,
++ *software distributed under the License is distributed on an
++ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++ * KIND, either express or implied.  See the License for the
++ *specific language governing permissions and limitations
++ *under the License.
++ */
++
++#ifndef CELIX_ICALC_H
++#define CELIX_ICALC_H
++
++namespace example {
++class ICalc {
++    public:
++        static constexpr const char * const NAME = "example::ICalc";
++        static constexpr const char * const VERSION = "1.0.0";
++        static constexpr const char * const CONSUMER_RANGE = "[1.0.0,2.0.0)";
++
++
++        virtual ~ICalc() = default;
++
++        virtual double calc(double input) = 0;
++    };
++}
++
++#endif //CELIX_ICALC_H
+diff --git a/examples/celix-examples/services_example_cxx/api/calc.h b/examples/celix-examples/services_example_cxx/api/calc.h
+new file mode 100644
+index 00000000..522dd767
+--- /dev/null
++++ b/examples/celix-examples/services_example_cxx/api/calc.h
+@@ -0,0 +1,43 @@
++/**
++ *Licensed to the Apache Software Foundation (ASF) under one
++ *or more contributor license agreements.  See the NOTICE file
++ *distributed with this work for additional information
++ *regarding copyright ownership.  The ASF licenses this file
++ *to you under the Apache License, Version 2.0 (the
++ *"License"); you may not use this file except in compliance
++ *with the License.  You may obtain a copy of the License at
++ *
++ *  http://www.apache.org/licenses/LICENSE-2.0
++ *
++ *Unless required by applicable law or agreed to in writing,
++ *software distributed under the License is distributed on an
++ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++ * KIND, either express or implied.  See the License for the
++ *specific language governing permissions and limitations
++ *under the License.
++ */
++
++#ifndef CALC_H_
++#define CALC_H_
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++#define CALC_NAME 			"org.example"
++#define CALC_VERSION 		"1.0.0"
++#define CALC_CONSUMER_RANGE   "[1.0.0,2.0.0)"
++
++
++struct calc_struct {
++	void *handle;
++	double (*calc)(double input);
++} ;
++
++typedef struct calc_struct calc_t;
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* CALC_H_ */
+diff --git a/examples/celix-examples/services_example_cxx/bar/CMakeLists.txt b/examples/celix-examples/services_example_cxx/bar/CMakeLists.txt
+deleted file mode 100644
+index c660ce6d..00000000
+--- a/examples/celix-examples/services_example_cxx/bar/CMakeLists.txt
++++ /dev/null
+@@ -1,41 +0,0 @@
+-# Licensed to the Apache Software Foundation (ASF) under one
+-# or more contributor license agreements.  See the NOTICE file
+-# distributed with this work for additional information
+-# regarding copyright ownership.  The ASF licenses this file
+-# to you under the Apache License, Version 2.0 (the
+-# "License"); you may not use this file except in compliance
+-# with the License.  You may obtain a copy of the License at
+-# 
+-#   http://www.apache.org/licenses/LICENSE-2.0
+-# 
+-# Unless required by applicable law or agreed to in writing,
+-# software distributed under the License is distributed on an
+-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+-# KIND, either express or implied.  See the License for the
+-# specific language governing permissions and limitations
+-# under the License.
+-
+-include_directories(
+-        private/include
+-)
+-
+-add_celix_bundle(bar_cxx
+-    SYMBOLIC_NAME Bar
+-    VERSION 1.0.0
+-    SOURCES
+-        private/src/Bar.cc
+-        private/src/BarActivator.cc
+-)
+-
+-target_compile_options(bar_cxx PUBLIC -Wall -Wextra -Weffc++ -Werror)
+-
+-IF(APPLE)
+-    target_link_libraries(bar_cxx PRIVATE -Wl,-all_load  dependency_manager_cxx_static)
+-else()
+-    if(ENABLE_ADDRESS_SANITIZER)
+-        #With asan there can be undefined symbols
+-        target_link_libraries(bar_cxx PRIVATE -Wl,--whole-archive  dependency_manager_cxx_static -Wl,--no-whole-archive)
+-    else()
+-        target_link_libraries(bar_cxx PRIVATE -Wl,--no-undefined -Wl,--whole-archive  dependency_manager_cxx_static -Wl,--no-whole-archive)
+-    endif()
+-endif()
+\ No newline at end of file
+diff --git a/examples/celix-examples/services_example_cxx/baz/CMakeLists.txt b/examples/celix-examples/services_example_cxx/baz/CMakeLists.txt
+deleted file mode 100644
+index ce5bfd0a..00000000
+--- a/examples/celix-examples/services_example_cxx/baz/CMakeLists.txt
++++ /dev/null
+@@ -1,41 +0,0 @@
+-# Licensed to the Apache Software Foundation (ASF) under one
+-# or more contributor license agreements.  See the NOTICE file
+-# distributed with this work for additional information
+-# regarding copyright ownership.  The ASF licenses this file
+-# to you under the Apache License, Version 2.0 (the
+-# "License"); you may not use this file except in compliance
+-# with the License.  You may obtain a copy of the License at
+-# 
+-#   http://www.apache.org/licenses/LICENSE-2.0
+-# 
+-# Unless required by applicable law or agreed to in writing,
+-# software distributed under the License is distributed on an
+-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+-# KIND, either express or implied.  See the License for the
+-# specific language governing permissions and limitations
+-# under the License.
+-
+-include_directories(
+-        private/include
+-)
+-
+-add_celix_bundle(baz_cxx
+-    SYMBOLIC_NAME Baz
+-    VERSION 1.0.0
+-    SOURCES
+-        private/src/Baz.cc
+-        private/src/BazActivator.cc
+-)
+-
+-target_compile_options(baz_cxx PUBLIC -Wall -Wextra -Weffc++ -Werror)
+-
+-IF(APPLE)
+-    target_link_libraries(baz_cxx PRIVATE  -Wl,-all_load  dependency_manager_cxx_static)
+-else()
+-    if(ENABLE_ADDRESS_SANITIZER)
+-        #With asan there can be undefined symbols
+-        target_link_libraries(baz_cxx PRIVATE -Wl,--whole-archive  dependency_manager_cxx_static -Wl,--no-whole-archive)
+-    else()
+-        target_link_libraries(baz_cxx PRIVATE -Wl,--no-undefined -Wl,--whole-archive  dependency_manager_cxx_static -Wl,--no-whole-archive)
+-    endif()
+-endif()
+diff --git a/examples/celix-examples/services_example_cxx/foo/CMakeLists.txt b/examples/celix-examples/services_example_cxx/foo/CMakeLists.txt
+deleted file mode 100644
+index ba2aa556..00000000
+--- a/examples/celix-examples/services_example_cxx/foo/CMakeLists.txt
++++ /dev/null
+@@ -1,41 +0,0 @@
+-# Licensed to the Apache Software Foundation (ASF) under one
+-# or more contributor license agreements.  See the NOTICE file
+-# distributed with this work for additional information
+-# regarding copyright ownership.  The ASF licenses this file
+-# to you under the Apache License, Version 2.0 (the
+-# "License"); you may not use this file except in compliance
+-# with the License.  You may obtain a copy of the License at
+-# 
+-#   http://www.apache.org/licenses/LICENSE-2.0
+-# 
+-# Unless required by applicable law or agreed to in writing,
+-# software distributed under the License is distributed on an
+-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+-# KIND, either express or implied.  See the License for the
+-# specific language governing permissions and limitations
+-# under the License.
+-
+-include_directories(
+-        private/include
+-)
+-
+-add_celix_bundle(foo_cxx
+-    SYMBOLIC_NAME Foo
+-    VERSION 1.0.0
+-    SOURCES
+-        private/src/Foo.cc
+-        private/src/FooActivator.cc
+-)
+-
+-target_compile_options(foo_cxx PUBLIC -Wall -Wextra -Weffc++ -Werror)
+-
+-IF(APPLE)
+-    target_link_libraries(foo_cxx PRIVATE -Wl,-all_load  dependency_manager_cxx_static)
+-else()
+-    if(ENABLE_ADDRESS_SANITIZER)
+-        #With asan there can be undefined symbols
+-        target_link_libraries(foo_cxx PRIVATE -Wl,--whole-archive  dependency_manager_cxx_static -Wl,--no-whole-archive)
+-    else()
+-        target_link_libraries(foo_cxx PRIVATE -Wl,--no-undefined -Wl,--whole-archive  dependency_manager_cxx_static -Wl,--no-whole-archive)
+-    endif()
+-endif()
+diff --git a/examples/celix-examples/services_example_cxx/src/ConsumerBundleActivator.cc b/examples/celix-examples/services_example_cxx/src/ConsumerBundleActivator.cc
+new file mode 100644
+index 00000000..5ad00fed
+--- /dev/null
++++ b/examples/celix-examples/services_example_cxx/src/ConsumerBundleActivator.cc
+@@ -0,0 +1,72 @@
++/**
++ *Licensed to the Apache Software Foundation (ASF) under one
++ *or more contributor license agreements.  See the NOTICE file
++ *distributed with this work for additional information
++ *regarding copyright ownership.  The ASF licenses this file
++ *to you under the Apache License, Version 2.0 (the
++ *"License"); you may not use this file except in compliance
++ *with the License.  You may obtain a copy of the License at
++ *
++ *  http://www.apache.org/licenses/LICENSE-2.0
++ *
++ *Unless required by applicable law or agreed to in writing,
++ *software distributed under the License is distributed on an
++ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++ * KIND, either express or implied.  See the License for the
++ *specific language governing permissions and limitations
++ *under the License.
++ */
++
++#include <iostream>
++#include <thread>
++
++#include "celix/BundleActivator.h"
++
++#include "ICalc.h"
++
++namespace {
++    class BundleActivator : public celix::IBundleActivator {
++    public:
++        BundleActivator(celix::BundleContext &_ctx) : ctx{_ctx} {}
++
++        virtual ~BundleActivator() {
++                this->useThread.join();
++        }
++
++    protected:
++        void use() {
++                while(this->running) {
++                        int count = 0;
++                        double total = 0;
++                        ctx.useServices<example::ICalc>(example::ICalc::NAME, [&](example::ICalc &calc, const celix::Properties &, const celix::Bundle&) {
++                                count++;
++                                total += calc.calc(1);
++                        });
++                        std::cout << "Called calc " << count << " times. Total is " << total << std::endl;
++                        std::this_thread::sleep_for(std::chrono::seconds(5));
++                }
++        }
++
++        void setRunning(bool r) {
++                std::lock_guard<std::mutex> lock{this->mutex};
++                this->running = r;
++        }
++
++        bool isRunning() {
++                std::lock_guard<std::mutex> lock{this->mutex};
++                return this->running;
++        }
++
++    private:
++        celix::BundleContext &ctx;
++        std::thread useThread{[this] { this->use(); }};
++
++        std::mutex mutex{}; //protects running
++        bool running{true};
++    };
++}
++
++celix::IBundleActivator* celix::createBundleActivator(celix::BundleContext &ctx) {
++    return new BundleActivator{ctx};
++}
++
+diff --git a/examples/celix-examples/services_example_cxx/src/ProviderBundleActivator.cc b/examples/celix-examples/services_example_cxx/src/ProviderBundleActivator.cc
+new file mode 100644
+index 00000000..fd8466e4
+--- /dev/null
++++ b/examples/celix-examples/services_example_cxx/src/ProviderBundleActivator.cc
+@@ -0,0 +1,98 @@
++/**
++ *Licensed to the Apache Software Foundation (ASF) under one
++ *or more contributor license agreements.  See the NOTICE file
++ *distributed with this work for additional information
++ *regarding copyright ownership.  The ASF licenses this file
++ *to you under the Apache License, Version 2.0 (the
++ *"License"); you may not use this file except in compliance
++ *with the License.  You may obtain a copy of the License at
++ *
++ *  http://www.apache.org/licenses/LICENSE-2.0
++ *
++ *Unless required by applicable law or agreed to in writing,
++ *software distributed under the License is distributed on an
++ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++ * KIND, either express or implied.  See the License for the
++ *specific language governing permissions and limitations
++ *under the License.
++ */
++
++#include <iostream>
++#include <thread>
++#include <mutex>
++#include <vector>
++
++#include "celix/BundleActivator.h"
++
++#include "ICalc.h"
++
++namespace {
++    class CalcImpl : public example::ICalc {
++        double calc(double input) override {
++            return input * 42.0;
++        }
++    };
++
++    class BundleActivator : public celix::IBundleActivator {
++    public:
++        BundleActivator(celix::BundleContext &ctx) {
++            /*
++             * This thread registers calc service to a max of 100, then unregistered the services and repeats.
++             */
++            th = std::thread{[this, &ctx]{
++                std::cout << "Starting service register thread" << std::endl;
++                CalcImpl calc{};
++                std::vector<long> svcIds{};
++                bool up = true;
++                while (this->isRunning()) {
++                    if (up) {
++                        celix::Properties props{};
++                        props[celix::Constants::SERVICE_RANKING] = "10"; //TODO random
++                        long svcId = ctx.registerService(example::ICalc::NAME, &calc, example::ICalc::VERSION, std::move(props));
++                        svcIds.push_back(svcId);
++                    } else {
++                        if (svcIds.size() > 0) {
++                            long svcId = svcIds.back();
++                            svcIds.pop_back();
++                            ctx.unregisterService(svcId);
++                        } else {
++                            up = true;
++                        }
++                    }
++                    if (svcIds.size() >= 100) {
++                        up = false;
++                    }
++                    std::this_thread::yield();
++                }
++                std::cout << "Exiting service register thread, services count is " << svcIds.size() << std::endl;
++                std::for_each(svcIds.begin(), svcIds.end(), [&ctx](long id){ctx.unregisterService(id);});
++
++            }};
++        }
++
++        virtual ~BundleActivator() {
++            this->setRunning(false);
++            th.join();
++        }
++
++        void setRunning(bool r) {
++            std::lock_guard<std::mutex> lock{this->mutex};
++            this->running = r;
++        }
++
++        bool isRunning() {
++            std::lock_guard<std::mutex> lock{this->mutex};
++            return this->running;
++        }
++    private:
++        std::thread th{};
++
++        std::mutex mutex{}; //protects running
++        bool running{true};
++    };
++}
++
++celix::IBundleActivator* celix::createBundleActivator(celix::BundleContext &ctx) {
++    return new BundleActivator{ctx};
++}
++
+diff --git a/framework/gtest/src/cxx_BundleContext_tests.cc b/framework/gtest/src/cxx_BundleContext_tests.cc
+index d1a6a06a..76870110 100644
+--- a/framework/gtest/src/cxx_BundleContext_tests.cc
++++ b/framework/gtest/src/cxx_BundleContext_tests.cc
+@@ -107,32 +107,35 @@ TEST_F(BundleContextTest, UseService) {
+ TEST_F(BundleContextTest, UseServices) {
+     auto &ctx = this->framework().getFrameworkContext();
+ 
+-    struct test_svc {
+-        int (*calc)(int input);
++    class ITestSvc {
++    public:
++        virtual ~ITestSvc(){};
++        virtual int calc(int input) = 0;
+     };
+-
+-    test_svc svc{};
+-    svc.calc = [](int input) -> int {
+-        return input * 42;
++    class TestImpl : public ITestSvc {
++    public:
++        virtual ~TestImpl(){};
++        int calc(int input) override { return input * 42; }
+     };
++    TestImpl svc{};
+ 
+-    long svcId1 = ctx.registerCService("test service", &svc);
++    long svcId1 = ctx.registerService<ITestSvc>("test service", &svc);
+     EXPECT_TRUE(svcId1 > 0);
+ 
+-    long svcId2 = ctx.registerCService("test service", &svc);
++    long svcId2 = ctx.registerService<ITestSvc>("test service", &svc);
+     EXPECT_TRUE(svcId2 > 0);
+ 
+ 
+     int result = 0;
+-    std::function<void(test_svc &svc, const celix::Properties&, const celix::Bundle&)> func = [&result](test_svc &svc, const celix::Properties&, const celix::Bundle&) {
++    auto func = [&result](ITestSvc &svc, const celix::Properties&, const celix::Bundle&) {
+         result += svc.calc(1);
+     };
+-    ctx.useServices("test service", "", "", func);
++    ctx.useServices<ITestSvc>("test service", func);
+     EXPECT_EQ(result, 84); //two times
+ 
+     ctx.unregisterService(svcId1);
+ 
+-    ctx.useServices("test service", "", "", func);
++    ctx.useServices<ITestSvc>("test service", func);
+     EXPECT_EQ(result, 126); //one time
+ 
+     ctx.unregisterService(svcId2);
+@@ -144,17 +147,19 @@ TEST_F(BundleContextTest, TrackService) {
+ 
+     int count = 0;
+ 
+-    struct test_svc {
+-        int (*calc)(int input);
++    class ITestSvc {
++    public:
++        virtual ~ITestSvc(){};
++        virtual int calc(int input) = 0;
+     };
+ 
+-    struct test_svc *svc1 = (struct test_svc*)0x100; //no ranking
+-    struct test_svc *svc2 = (struct test_svc*)0x200; //no ranking
+-    struct test_svc *svc3 = (struct test_svc*)0x300; //10 ranking
+-    struct test_svc *svc4 = (struct test_svc*)0x400; //5 ranking
++    ITestSvc *svc1 = (ITestSvc*)0x100; //no ranking
++    ITestSvc *svc2 = (ITestSvc*)0x200; //no ranking
++    ITestSvc *svc3 = (ITestSvc*)0x300; //10 ranking
++    ITestSvc *svc4 = (ITestSvc*)0x400; //5 ranking
+ 
+ 
+-    auto set = [&](struct test_svc *svc, const celix::Properties &, const celix::Bundle &) {
++    auto set = [&](ITestSvc *svc, const celix::Properties &, const celix::Bundle &) {
+         static int callCount = 0;
+         callCount += 1;
+         if (callCount == 1) {
+@@ -175,7 +180,7 @@ TEST_F(BundleContextTest, TrackService) {
+     long svcId2 = ctx.registerService("NA", svc2);
+ 
+     //starting tracker should lead to first set call
+-    long trackerId = ctx.trackService<struct test_svc>("NA", "", "", set);
++    long trackerId = ctx.trackService<ITestSvc>("NA", set);
+     EXPECT_TRUE(trackerId > 0);
+ 
+     //register svc3 should lead to second set call
+diff --git a/framework/include/celix/BundleContext.h b/framework/include/celix/BundleContext.h
+index b26cdd04..e6da72f1 100644
+--- a/framework/include/celix/BundleContext.h
++++ b/framework/include/celix/BundleContext.h
+@@ -98,11 +98,9 @@ namespace celix {
+         template<typename I>
+         long trackService(
+                 const std::string &serviceName,
+-                const std::string &versionRange,
+-                const std::string &filter,
+                 std::function<void(I *svc, const celix::Properties& props, const celix::Bundle &bnd)> set
+         ) noexcept {
+-            return this->trackServiceInternal(serviceName, versionRange, filter, [set](void *voidSvc, const celix::Properties& props, const celix::Bundle &bnd) {
++            return this->trackServiceInternal(serviceName, [set](void *voidSvc, const celix::Properties& props, const celix::Bundle &bnd) {
+                 I* typedSvc = static_cast<I*>(voidSvc);
+                 set(typedSvc, props, bnd);
+             });
+@@ -123,12 +121,10 @@ namespace celix {
+         template<typename I>
+         long trackServices(
+                 const std::string &serviceName,
+-                const std::string &versionRange,
+-                const std::string &filter,
+                 std::function<void(I *svc, const celix::Properties& props, const celix::Bundle &bnd)> add,
+                 std::function<void(I *svc, const celix::Properties& props, const celix::Bundle &bnd)> remove
+         ) noexcept {
+-            return this->trackServicesInternal(serviceName, versionRange, filter,
++            return this->trackServicesInternal(serviceName,
+                                                [add](void *voidSvc, const celix::Properties& props, const celix::Bundle &bnd) {
+                                                    I *typedSvc = static_cast<I *>(voidSvc);
+                                                    add(typedSvc, props, bnd);
+@@ -141,7 +137,8 @@ namespace celix {
+         }
+ 
+         //TODO make add / remove service refs??
+-        //TODO missing lang for track services
++        //TODO add trackService(s)WithOptions
++        //TODO add trackCService(s) variants
+ 
+         /**
+          * Note use fucntion by const reference. Only used during the call.
+@@ -150,27 +147,31 @@ namespace celix {
+          * @return
+          */
+         template<typename I>
+-        bool useService(long serviceId, const std::string &serviceName /*sanity*/, const std::function<void(I &svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept {
++        bool useService(long serviceId, const std::string &/*serviceName*/ /*sanity*/, const std::function<void(I &svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &/*use*/) noexcept {
+             std::string filter = std::string{"(service.id="} + std::to_string(serviceId) + std::string{")"};
+-            return this->useService<I>(serviceName, "", filter, use);
++            //TODO use useServiceWithOptions return this->useService<I>(serviceName, "", filter, use);
++            return false;
+         }
+ 
+         template<typename I>
+-        bool useService(const std::string &serviceName, const std::string &versionRange, const std::string &filter, const std::function<void(I &svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept {
+-            return this->useServiceInternal(serviceName, versionRange, filter, [use](void *voidSvc, const celix::Properties &props, const celix::Bundle &svcOwner) {
++        bool useService(const std::string &serviceName, const std::function<void(I &svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept {
++            return this->useServiceInternal(serviceName, [use](void *voidSvc, const celix::Properties &props, const celix::Bundle &svcOwner) {
+                 I *typedSvc = static_cast<I*>(voidSvc);
+                 use(*typedSvc, props, svcOwner);
+             });
+         }
+ 
+         template<typename I>
+-        void useServices(const std::string &serviceName, const std::string &versionRange, const std::string &filter, const std::function<void(I &svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept {
+-            this->useServicesInternal(serviceName, filter, versionRange, [use](void *voidSvc, const celix::Properties &props, const celix::Bundle &svcOwner) {
++        void useServices(const std::string &serviceName, const std::function<void(I &svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept {
++            this->useServicesInternal(serviceName, [use](void *voidSvc, const celix::Properties &props, const celix::Bundle &svcOwner) {
+                 I *typedSvc = static_cast<I*>(voidSvc);
+                 use(*typedSvc, props, svcOwner);
+             });
+         }
+ 
++        //TODO add useService(s)WithOptions
++        //TODO add useCService(s) variants
++
+         /**
+          * Note ordered by service rank.
+          */
+@@ -225,20 +226,16 @@ namespace celix {
+         virtual long registerServiceInternal(const std::string &serviceName, void *svc, const std::string &version, const std::string &lang, celix::Properties props) noexcept = 0;
+ 
+         virtual long trackServiceInternal(const std::string &serviceName,
+-                                         const std::string &versionRange,
+-                                         const std::string &filter,
+                                          std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> set) noexcept = 0;
+ 
+         virtual long trackServicesInternal(
+                 const std::string &serviceName,
+-                const std::string &versionRange,
+-                const std::string &filter,
+                 std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> add,
+                 std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> remove
+         ) noexcept = 0;
+ 
+-        virtual bool useServiceInternal(const std::string &serviceName, const std::string &versionRange, const std::string &filter, const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept = 0;
+-        virtual void useServicesInternal(const std::string &serviceName, const std::string &versionRange, const std::string &filter, const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept = 0;
++        virtual bool useServiceInternal(const std::string &serviceName, const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept = 0;
++        virtual void useServicesInternal(const std::string &serviceName, const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept = 0;
+     };
+ 
+ }
+diff --git a/framework/include/celix/impl/BundleContextImpl.h b/framework/include/celix/impl/BundleContextImpl.h
+index 80ee6622..cc2bc0e3 100644
+--- a/framework/include/celix/impl/BundleContextImpl.h
++++ b/framework/include/celix/impl/BundleContextImpl.h
+@@ -71,15 +71,15 @@ namespace celix {
+                 celix_bundleContext_unregisterService(this->c_ctx, serviceId);
+             }
+ 
+-            std::vector<long> findServices(const std::string &serviceName, const std::string &versionRange, const std::string &filter, const std::string &/*lang = ""*/) noexcept override  {
++            std::vector<long> findServices(const std::string &/*serviceName*/, const std::string &/*versionRange*/, const std::string &/*filter*/, const std::string &/*lang = ""*/) noexcept override  {
+                 std::vector<long> result{};
+-                auto use = [&result](void *, const celix::Properties &props, const celix::Bundle &) {
+-                    long id = celix::getProperty(props, OSGI_FRAMEWORK_SERVICE_ID, -1);
+-                    if (id >= 0) {
+-                        result.push_back(id);
+-                    }
+-                };
+-                this->useServicesInternal(serviceName, versionRange, filter, use);
++//                auto use = [&result](void *, const celix::Properties &props, const celix::Bundle &) {
++//                    long id = celix::getProperty(props, OSGI_FRAMEWORK_SERVICE_ID, -1);
++//                    if (id >= 0) {
++//                        result.push_back(id);
++//                    }
++//                };
++                //TODO useServicesWithOptions this->useServicesInternal(serviceName, versionRange, filter, use);
+                 return result;
+             }
+ 
+@@ -175,10 +175,8 @@ namespace celix {
+             }
+ 
+             long trackServiceInternal(const std::string &serviceName,
+-                                      const std::string &versionRange,
+-                                      const std::string &filter,
+                                       std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> set) noexcept override  {
+-                celix_service_tracker_options_t opts;
++                celix_service_tracking_options_t opts;
+                 std::memset(&opts, 0, sizeof(opts));
+ 
+                 auto c_set = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_bnd) {
+@@ -189,12 +187,8 @@ namespace celix {
+                     (entry->set)(svc, props, bnd);
+                 };
+                 const char *cname = serviceName.empty() ? nullptr : serviceName.c_str();
+-                const char *crange = versionRange.empty() ? nullptr : versionRange.c_str();
+-                const char *cfilter = filter.empty() ? nullptr : filter.c_str();
+ 
+                 opts.serviceName = cname;
+-                opts.versionRange = crange;
+-                opts.filter = cfilter;
+                 opts.lang = CELIX_FRAMEWORK_SERVICE_CXX_LANGUAGE;
+ 
+                 auto te = std::unique_ptr<TrackEntry>{new TrackEntry{}};
+@@ -213,12 +207,10 @@ namespace celix {
+ 
+             long trackServicesInternal(
+                     const std::string &serviceName,
+-                    const std::string &versionRange,
+-                    const std::string &filter,
+                     std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> add,
+                     std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> remove
+             ) noexcept override {
+-                celix_service_tracker_options_t opts;
++                celix_service_tracking_options_t opts;
+                 std::memset(&opts, 0, sizeof(opts));
+ 
+                 auto c_add = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_bnd) {
+@@ -236,13 +228,7 @@ namespace celix {
+                     (entry->remove)(svc, props, bnd);
+                 };
+ 
+-                const char *cname = serviceName.empty() ? nullptr : serviceName.c_str();
+-                const char *crange = versionRange.empty() ? nullptr : versionRange.c_str();
+-                const char *cfilter = filter.empty() ? nullptr : filter.c_str();
+-
+-                opts.serviceName = cname;
+-                opts.versionRange = crange;
+-                opts.filter = cfilter;
++                opts.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();
+                 opts.lang = CELIX_FRAMEWORK_SERVICE_CXX_LANGUAGE;
+ 
+                 auto te = std::unique_ptr<TrackEntry>{new TrackEntry{}};
+@@ -263,8 +249,6 @@ namespace celix {
+ 
+             bool useServiceInternal(
+                     const std::string &serviceName,
+-                    const std::string &versionRange,
+-                    const std::string &filter,
+                     const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept override {
+                 auto c_use = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_svcOwner) {
+                     auto *fn = static_cast<const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> *>(handle);
+@@ -273,16 +257,20 @@ namespace celix {
+                     celix::impl::BundleImpl bnd{m_bnd};
+                     (*fn)(svc, props, bnd);
+                 };
+-                const char *cname = serviceName.empty() ? nullptr : serviceName.c_str();
+-                const char *crange = versionRange.empty() ? nullptr : versionRange.c_str();
+-                const char *cfilter = filter.empty() ? nullptr : filter.c_str();
+-                return celix_bundleContext_useService(this->c_ctx, cname, crange, cfilter, (void*)(&use), c_use);
++
++                celix_service_use_options_t opts;
++                std::memset(&opts, 0, sizeof(opts));
++
++                opts.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();;
++                opts.lang = celix::Constants::SERVICE_CXX_LANG;
++                opts.callbackHandle = (void*)&use;
++                opts.use = c_use;
++
++                return celix_bundleContext_useServiceWithOptions(this->c_ctx, &opts);
+             }
+ 
+             void useServicesInternal(
+                     const std::string &serviceName,
+-                    const std::string &versionRange,
+-                    const std::string &filter,
+                     const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept override {
+                 auto c_use = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_svcOwner) {
+                     auto *fn = static_cast<const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> *>(handle);
+@@ -291,10 +279,16 @@ namespace celix {
+                     celix::impl::BundleImpl bnd{m_bnd};
+                     (*fn)(svc, props, bnd);
+                 };
+-                const char *cname = serviceName.empty() ? nullptr : serviceName.c_str();
+-                const char *crange = versionRange.empty() ? nullptr : versionRange.c_str();
+-                const char *cfilter = filter.empty() ? nullptr : filter.c_str();
+-                celix_bundleContext_useServices(this->c_ctx, cname, crange, cfilter, (void*)(&use), c_use);
++
++                celix_service_use_options_t opts;
++                std::memset(&opts, 0, sizeof(opts));
++
++                opts.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();;
++                opts.lang = celix::Constants::SERVICE_CXX_LANG;
++                opts.callbackHandle = (void*)&use;
++                opts.use = c_use;
++
++                celix_bundleContext_useServicesWithOptions(this->c_ctx, &opts);
+             }
+ 
+         private:

http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/celix-examples/CMakeLists.txt b/examples/celix-examples/CMakeLists.txt
index fd2ec1c..bd70065 100644
--- a/examples/celix-examples/CMakeLists.txt
+++ b/examples/celix-examples/CMakeLists.txt
@@ -23,11 +23,13 @@ endif ()
 if (EXAMPLES)
     add_subdirectory(bundle_example_cxx)
 
+    add_subdirectory(services_example_cxx)
+
     add_subdirectory(hello_world)
     add_subdirectory(hello_world_test)
 
     add_subdirectory(services_example_c)
-    add_subdirectory(services_example_cxx)
+    add_subdirectory(best_practice_example_cxx)
 
     add_subdirectory(dm_example)
     add_subdirectory(dm_example_cxx)

http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_cxx/CMakeLists.txt b/examples/celix-examples/best_practice_example_cxx/CMakeLists.txt
new file mode 100644
index 0000000..faa7c00
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_cxx/CMakeLists.txt
@@ -0,0 +1,62 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+add_library(cxx_services_example_api INTERFACE)
+target_include_directories(cxx_services_example_api INTERFACE api)
+
+add_celix_bundle(cxx_foo
+        VERSION 1.0.0
+        SOURCES
+        foo/Foo.cc
+        foo/Foo.h
+        foo/FooActivator.cc
+        foo/FooActivator.h
+    )
+target_link_libraries(cxx_foo PRIVATE cxx_services_example_api)
+
+add_celix_bundle(cxx_bar
+        VERSION 1.0.0
+        SOURCES
+            bar/Bar.cc
+            bar/Bar.h
+            bar/BarActivator.cc
+            bar/BarActivator.h
+)
+target_link_libraries(cxx_bar PRIVATE cxx_services_example_api)
+
+add_celix_bundle(cxx_baz
+    VERSION 1.0.0
+    SOURCES
+        baz/Baz.cc
+        baz/Baz.h
+        baz/BazActivator.cc
+        baz/BazActivator.h
+)
+target_link_libraries(cxx_baz PRIVATE cxx_services_example_api)
+
+add_celix_container(best_practice_example_cxx
+    GROUP services_example
+    COPY
+    BUNDLES
+        Celix::shell
+        Celix::shell_tui
+        cxx_bar
+        cxx_foo
+        cxx_baz
+    PROPERTIES
+        example=value
+)

http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/api/IAnotherExample.h
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_cxx/api/IAnotherExample.h b/examples/celix-examples/best_practice_example_cxx/api/IAnotherExample.h
new file mode 100644
index 0000000..2ed4d6d
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_cxx/api/IAnotherExample.h
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef IANOTHER_EXAMPLE_H
+#define IANOTHER_EXAMPLE_H
+
+
+class IAnotherExample {
+public:
+    static constexpr const char * const VERSION = "1.0.0";
+    static constexpr const char * const CONSUMER_RANGE = "[1.0.0,2.0.0)";
+
+    virtual ~IAnotherExample() = default;
+
+    virtual double method(int arg1, double arg2) = 0;
+};
+
+#endif //IANOTHER_EXAMPLE_H

http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/api/example.h
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_cxx/api/example.h b/examples/celix-examples/best_practice_example_cxx/api/example.h
new file mode 100644
index 0000000..68ce0e3
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_cxx/api/example.h
@@ -0,0 +1,43 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#ifndef EXAMPLE_H_
+#define EXAMPLE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define EXAMPLE_NAME 			"org.example"
+#define EXAMPLE_VERSION 		"1.0.0"
+#define EXAMPLE_CONSUMER_RANGE   "[1.0.0,2.0.0)"
+
+
+struct example_struct {
+	void *handle;
+	int (*method)(void *handle, int arg1, double arg2, double *result);
+} ;
+
+typedef struct example_struct example_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* EXAMPLE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/bar/Bar.cc
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_cxx/bar/Bar.cc b/examples/celix-examples/best_practice_example_cxx/bar/Bar.cc
new file mode 100644
index 0000000..7490005
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_cxx/bar/Bar.cc
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "Bar.h"
+#include <iostream>
+
+void Bar::init() {
+    std::cout << "init Bar\n";
+}
+
+void Bar::start() {
+    std::cout << "start Bar\n";
+}
+
+void Bar::stop() {
+    std::cout << "stop Bar\n";
+}
+
+void Bar::deinit() {
+    std::cout << "deinit Bar\n";
+}
+
+double Bar::method(int arg1, double arg2) {
+    double update = (this->seed + arg1) * arg2;
+    return update;
+}
+
+int Bar::cMethod(int arg1, double arg2, double *out) {
+    double r = this->method(arg1, arg2);
+    *out = r;
+    return 0;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/bar/Bar.h
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_cxx/bar/Bar.h b/examples/celix-examples/best_practice_example_cxx/bar/Bar.h
new file mode 100644
index 0000000..799f8a9
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_cxx/bar/Bar.h
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef BAR_H
+#define BAR_H
+
+#include "IAnotherExample.h"
+
+class Bar : public IAnotherExample {
+    const double seed = 42;
+public:
+    Bar() = default;
+    virtual ~Bar() = default;
+
+    void init();
+    void start();
+    void stop();
+    void deinit();
+
+    virtual double method(int arg1, double arg2) override; //implementation of IAnotherExample::method
+    int cMethod(int arg1, double arg2, double *out); //implementation of example_t->method;
+};
+
+#endif //BAR_H

http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.cc
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.cc b/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.cc
new file mode 100644
index 0000000..1dc5a7e
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.cc
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "Bar.h"
+#include "BarActivator.h"
+
+#include "celix/BundleActivator.h"
+
+celix::IBundleActivator* celix::createBundleActivator(celix::BundleContext &ctx) {
+    return new BarActivator{ctx};
+}
+
+BarActivator::BarActivator(celix::BundleContext& ctx) {
+    auto &mng = ctx.getDependencyManager();
+    auto bar = std::unique_ptr<Bar>{new Bar{}};
+
+    Properties props;
+    props["meta.info.key"] = "meta.info.value";
+
+    Properties cProps;
+    cProps["also.meta.info.key"] = "also.meta.info.value";
+
+    this->cExample.handle = bar.get();
+    this->cExample.method = [](void *handle, int arg1, double arg2, double *out) {
+        Bar* bar = static_cast<Bar*>(handle);
+        return bar->cMethod(arg1, arg2, out);
+    };
+
+    mng.createComponent(std::move(bar))  //using a pointer a instance. Also supported is lazy initialization (default constructor needed) or a rvalue reference (move)
+        .addInterface<IAnotherExample>(IAnotherExample::VERSION, props)
+        .addCInterface(&this->cExample, EXAMPLE_NAME, EXAMPLE_VERSION, cProps)
+        .setCallbacks(&Bar::init, &Bar::start, &Bar::stop, &Bar::deinit);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.h
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.h b/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.h
new file mode 100644
index 0000000..8642c4f
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.h
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef BAR_ACTIVATOR_H
+#define BAR_ACTIVATOR_H
+
+#include "celix/IBundleActivator.h"
+#include "example.h"
+
+class BarActivator : public celix::IBundleActivator {
+public:
+    BarActivator(celix::BundleContext &ctx);
+    virtual ~BarActivator() = default;
+private:
+    example_t cExample {nullptr, nullptr};
+};
+
+#endif //BAR_ACTIVATOR_H

http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/baz/Baz.cc
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_cxx/baz/Baz.cc b/examples/celix-examples/best_practice_example_cxx/baz/Baz.cc
new file mode 100644
index 0000000..bf258fb
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_cxx/baz/Baz.cc
@@ -0,0 +1,84 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "Baz.h"
+#include <iostream>
+
+void Baz::start() {
+    std::cout << "start Baz\n";
+    this->running = true;
+    pollThread = std::thread {&Baz::poll, this};
+}
+
+void Baz::stop() {
+    std::cout << "stop Baz\n";
+    this->running = false;
+    this->pollThread.join();
+}
+
+void Baz::addAnotherExample(IAnotherExample *e) {
+    std::lock_guard<std::mutex> lock(this->lock_for_examples);
+    this->examples.push_back(e);
+}
+
+void Baz::removeAnotherExample(IAnotherExample *e) {
+    std::lock_guard<std::mutex> lock(this->lock_for_examples);
+    this->examples.remove(e);
+}
+
+void Baz::addExample(const example_t *e) {
+    std::lock_guard<std::mutex> lock(this->lock_for_cExamples);
+    this->cExamples.push_back(e);
+}
+
+void Baz::removeExample(const example_t *e) {
+    std::lock_guard<std::mutex> lock(this->lock_for_cExamples);
+    this->cExamples.remove(e);
+}
+
+void Baz::poll() {
+    double r1 = 1.0;
+    double r2 = 1.0;
+    while (this->running) {
+        //c++ service required -> if component started always available
+
+        {
+            std::lock_guard<std::mutex> lock(this->lock_for_examples);
+            int index = 0;
+            for (IAnotherExample *e : this->examples) {
+                r1 = e->method(3, r1);
+                std::cout << "Result IAnotherExample " << index++ << " is " << r1 << "\n";
+            }
+        }
+
+
+        {
+            std::lock_guard<std::mutex> lock(this->lock_for_cExamples);
+            int index = 0;
+            for (const example_t *e : this->cExamples) {
+                double out;
+                e->method(e->handle, 4, r2, &out);
+                r2 = out;
+                std::cout << "Result example_t " << index++ << " is " << r2 << "\n";
+            }
+        }
+
+        std::this_thread::sleep_for(std::chrono::milliseconds(4000));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/baz/Baz.h
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_cxx/baz/Baz.h b/examples/celix-examples/best_practice_example_cxx/baz/Baz.h
new file mode 100644
index 0000000..d881627
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_cxx/baz/Baz.h
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef BAZ_H
+#define BAZ_H
+
+#include "example.h"
+#include "IAnotherExample.h"
+#include <thread>
+#include <list>
+#include <mutex>
+
+class Baz  {
+    std::list<IAnotherExample*> examples {};
+    std::mutex lock_for_examples {};
+
+    std::list<const example_t*> cExamples {};
+    std::mutex lock_for_cExamples {};
+
+    std::thread pollThread {};
+    bool running = false;
+public:
+    Baz() = default;
+    virtual ~Baz() = default;
+
+    void start();
+    void stop();
+
+    void addAnotherExample(IAnotherExample* e);
+    void removeAnotherExample(IAnotherExample* e);
+
+    void addExample(const example_t* e);
+    void removeExample(const example_t* e);
+
+    void poll();
+};
+
+#endif //BAZ_H

http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.cc
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.cc b/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.cc
new file mode 100644
index 0000000..a3d3a4f
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.cc
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "Baz.h"
+#include "BazActivator.h"
+
+#include "celix/BundleActivator.h"
+
+celix::IBundleActivator* celix::createBundleActivator(celix::BundleContext &ctx) {
+    return new BazActivator{ctx};
+}
+
+BazActivator::BazActivator(celix::BundleContext& ctx) {
+    auto &mng = ctx.getDependencyManager();
+    Component<Baz>& cmp = mng.createComponent<Baz>()
+        .setCallbacks(nullptr, &Baz::start, &Baz::stop, nullptr);
+
+    cmp.createServiceDependency<IAnotherExample>()
+            .setRequired(true)
+            .setStrategy(DependencyUpdateStrategy::locking)
+            .setVersionRange(IAnotherExample::CONSUMER_RANGE)
+            .setCallbacks(&Baz::addAnotherExample, &Baz::removeAnotherExample);
+
+    cmp.createCServiceDependency<example_t>(EXAMPLE_NAME)
+            .setRequired(false)
+            .setStrategy(DependencyUpdateStrategy::locking)
+            .setVersionRange(EXAMPLE_CONSUMER_RANGE)
+            .setCallbacks(&Baz::addExample, &Baz::removeExample);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.h
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.h b/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.h
new file mode 100644
index 0000000..e1a7c38
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.h
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef BAZ_ACTIVATOR_H
+#define BAZ_ACTIVATOR_H
+
+#include "celix/IBundleActivator.h"
+
+class BazActivator : public celix::IBundleActivator {
+public:
+    BazActivator(celix::BundleContext &ctx);
+    virtual ~BazActivator() = default;
+};
+
+#endif //BAZ_ACTIVATOR_H

http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/foo/Foo.cc
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_cxx/foo/Foo.cc b/examples/celix-examples/best_practice_example_cxx/foo/Foo.cc
new file mode 100644
index 0000000..241513c
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_cxx/foo/Foo.cc
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "Foo.h"
+#include <iostream>
+
+void Foo::start() {
+    std::cout << "start Foo\n";
+    this->running = true;
+    pollThread = std::thread {&Foo::poll, this};
+}
+
+void Foo::stop() {
+    std::cout << "stop Foo\n";
+    this->running = false;
+    this->pollThread.join();
+}
+
+void Foo::setAnotherExample(IAnotherExample *e) {
+    this->example = e;
+}
+
+void Foo::setExample(const example_t *e) {
+    this->cExample = e;
+}
+
+void Foo::poll() {
+    double r1 = 1.0;
+    double r2 = 1.0;
+    while (this->running) {
+        //c++ service required -> if component started always available
+        r1 = this->example->method(3, r1);
+        std::cout << "Result IAnotherExample is " << r1 << "\n";
+
+        //c service is optional, can be nullptr
+        if (this->cExample != nullptr) {
+            double out;
+            this->cExample->method(this->cExample->handle, 4, r2, &out);
+            r2 = out;
+            std::cout << "Result example_t is " << r2 << "\n";
+        }
+        std::this_thread::sleep_for(std::chrono::milliseconds(5000));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/foo/Foo.h
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_cxx/foo/Foo.h b/examples/celix-examples/best_practice_example_cxx/foo/Foo.h
new file mode 100644
index 0000000..0035b77
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_cxx/foo/Foo.h
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef FOO_H
+#define FOO_H
+
+#include "example.h"
+#include "IAnotherExample.h"
+#include <thread>
+
+class Foo  {
+    IAnotherExample* example {nullptr};
+    const example_t* cExample {nullptr};
+    std::thread pollThread {};
+    bool running = false;
+public:
+    Foo() = default;
+    virtual ~Foo() = default;
+
+    Foo(const Foo&) = delete;
+    Foo& operator=(const Foo&) = delete;
+
+    void start();
+    void stop();
+
+    void setAnotherExample(IAnotherExample* e);
+    void setExample(const example_t* e);
+
+    void poll();
+};
+
+#endif //FOO_H

http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.cc
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.cc b/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.cc
new file mode 100644
index 0000000..719da16
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.cc
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "Foo.h"
+#include "FooActivator.h"
+
+#include "celix/BundleActivator.h"
+
+celix::IBundleActivator* celix::createBundleActivator(celix::BundleContext &ctx) {
+    return new FooActivator{ctx};
+}
+
+FooActivator::FooActivator(celix::BundleContext& ctx) {
+    auto &mng = ctx.getDependencyManager();
+    Component<Foo>& cmp = mng.createComponent<Foo>()
+        .setCallbacks(nullptr, &Foo::start, &Foo::stop, nullptr);
+
+    cmp.createServiceDependency<IAnotherExample>()
+            .setRequired(true)
+            .setVersionRange(IAnotherExample::CONSUMER_RANGE)
+            .setCallbacks(&Foo::setAnotherExample);
+
+    cmp.createCServiceDependency<example_t>(EXAMPLE_NAME)
+            .setRequired(false)
+            .setVersionRange(EXAMPLE_CONSUMER_RANGE)
+            .setCallbacks(&Foo::setExample);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.h
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.h b/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.h
new file mode 100644
index 0000000..a79d365
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.h
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef FOO_ACTIVATOR_H
+#define FOO_ACTIVATOR_H
+
+#include "celix/IBundleActivator.h"
+
+class FooActivator : public celix::IBundleActivator {
+private:
+public:
+    FooActivator(celix::BundleContext &ctx);
+    virtual ~FooActivator() = default;
+};
+
+#endif //FOO_ACTIVATOR_H

http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc
----------------------------------------------------------------------
diff --git a/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc b/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc
index 5687ff0..367d1dc 100644
--- a/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc
+++ b/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc
@@ -24,14 +24,15 @@
 namespace {
     class BundleActivator : public celix::IBundleActivator {
     public:
-        BundleActivator(celix::BundleContext &_ctx) : ctx{_ctx} {
-            std::cout << "Hello world from C++ bundle with id " << ctx.getBundle().getBundleId() << std::endl;
+        BundleActivator(celix::BundleContext &) {
+            //std::cout << "Hello world from C++ bundle with id " << ctx.getBundle().getBundleId() << std::endl;
+            std::cout << "Hello world from C++ bundle " << std::endl;
         }
         virtual ~BundleActivator() {
-            std::cout << "Goodbye world from C++ bundle with id " << ctx.getBundle().getBundleId() << std::endl;
+            //std::cout << "Goodbye world from C++ bundle with id " << ctx.getBundle().getBundleId() << std::endl;
         }
     protected:
-        celix::BundleContext &ctx;
+        //celix::BundleContext &ctx;
     };
 }