#1 Re: Bug Reports » ServiceReference#GetProperty method » 2012-05-08 23:11:38

Makes sense! Thanks smile
I have a some more questions in the pipe line but it will wait until tomorrow, good night!

#2 Bug Reports » ServiceReference#GetProperty method » 2012-05-08 23:03:19

simon
Replies: 2

Hey again,

I am not sure if this is a bug, but the ServiceReference#GetProperty method seems to return properties (at least the ObjectClass property) surrounded with parentheses:

I registered a service under the name "foo" in a separate module, and the following code:

	auto refs = GetModuleContext()->GetServiceReferences("");
	for (auto it = refs.begin(); it != refs.end(); ++it) {
		cout << (*it).GetProperty(ServiceConstants::OBJECTCLASS()) << endl;
	}

outputs "(foo)" rather than "foo".

Bug/no bug?

#3 Re: General Discussions & Feedback » Loading multiple modules » 2012-05-08 23:00:01

Thanks! I had moved to a C-cast because the compiler complained without usBase.h, and I did not think it made a difference besides the fact that it might be more prone to crashes.

I have everything working now.

#4 Re: General Discussions & Feedback » Loading multiple modules » 2012-05-08 17:57:10

Ok, I posted a bit fast sad.

The service is found, but calling dictionaryService->checkWord("Tutorial") doesn't seem to work. Actually I can call any method I define on the service, but if I add a debug trace in the method definition (service- side) it is not displayed, and the result displayed is always some random number.

$ ./build.sh && LD_LIBRARY_PATH="/usr/local/lib" ./testApp 
Success
I'm here!!!
CppMicroServices
MainModule
DictionaryServiceModule
1
(foo)
get service ref foo for module MainModule = 1 refs
Dictionary contains 'Tutorial': 99

(I also tried with a method "toUppercase" in DictionaryService and it doesn't work either).

#5 Re: General Discussions & Feedback » Loading multiple modules » 2012-05-08 14:09:17

Hi and thanks! I got it working following your instructions smile.

I'll post a bug report now, but this is a holiday here so I'll be back for more questions probably tomorrow wink.

#6 General Discussions & Feedback » Loading multiple modules » 2012-05-07 19:42:33

simon
Replies: 5

Hi again smile

I'm trying to get CppMicroServices running in a configuration where I load several modules... and use different services and my efforts have failed so far.

What I'd like, in different projects:

  • A Launcher: references different modules (by path?) and loads them.

  • Module A registering service "X"

  • Module B using service "X"

So far, I managed to write Module A  getting a simple launcher ready. (splitting the launcher in half to isolate Module B is next in my TODO list).

The launcher loads modules A and tries to use module A's service after loading it (I reused the facility provided by SharedLibraryHandle in usTestUtilSharedLibrary.cpp). Once loaded, I can use ModuleRegistry::GetMoodules() to see all loaded modules properly as expected.
However, my service is unavailable: at no point Module A's activator is even called.

I am using the "shared lib" mode and I did not find, so far, a way to "activate" the module: my module shows as "loaded" when calling the Module#isLoaded() method. Loading it is not enough, and I did not find where and how the system calls the Load() method of the activator, where the service is registered. I saw code dealing with this in a static way (having an extern pointer on test activators), but I would like to get it running in a shared way (I imagine a dlsym call to find the activator's handle -- which I do find -- then a call to Load(), but I would expect the system to handle this).

Here is the code...

Module A exports the DictionaryService

//! [Activator]
#include "DictionaryService.h"

#include <usModuleActivator.h>
#include <usModuleContext.h>
#include <usServiceProperties.h>

// Replace that include with your own base class declaration
#include <usBase.h>

#include <algorithm>
#include <memory>

US_USE_NAMESPACE

/**
 * This class implements a module activator that uses the module
 * context to register an English language dictionary service
 * with the C++ Micro Services registry during static initialization
 * of the module. The dictionary service interface is
 * defined in a separate file and is implemented by a nested class.
 */
class US_ABI_LOCAL MyActivator : public ModuleActivator
{

private:

  /**
   * A private inner class that implements a dictionary service;
   * see DictionaryService for details of the service.
   */
  class DictionaryImpl : public Base, public DictionaryService
  {
    // The set of words contained in the dictionary.
    US_UNORDERED_SET_TYPE<std::string> m_dictionary;

  public:

    DictionaryImpl()
    {
      m_dictionary.insert("welcome");
      m_dictionary.insert("to");
      m_dictionary.insert("the");
      m_dictionary.insert("micro");
      m_dictionary.insert("services");
      m_dictionary.insert("tutorial");
    }

    /**
     * Implements DictionaryService.checkWord(). Determines
     * if the passed in word is contained in the dictionary.
     * @param word the word to be checked.
     * @return true if the word is in the dictionary,
     *         false otherwise.
     **/
    bool checkWord(const std::string& word)
    {
      std::string lword(word);
      std::transform(lword.begin(), lword.end(), lword.begin(), ::tolower);

      return m_dictionary.find(lword) != m_dictionary.end();
    }
  };

  std::auto_ptr<DictionaryImpl> m_dictionaryService;


public:

  /**
   * Implements ModuleActivator::Load(). Registers an
   * instance of a dictionary service using the module context;
   * attaches properties to the service that can be queried
   * when performing a service look-up.
   * @param context the context for the module.
   */
  void Load(ModuleContext* context)
  {
	std::cout << "I'm here!!!" << std::endl;
    m_dictionaryService.reset(new DictionaryImpl);
    ServiceProperties props;
    props["Language"] = std::string("English");
    context->RegisterService("foo", m_dictionaryService.get(), props);
  }

  /**
   * Implements ModuleActivator::Unload(). Does nothing since
   * the C++ Micro Services library will automatically unregister any registered services.
   * @param context the context for the module.
   */
  void Unload(ModuleContext* /*context*/)
  {
    // NOTE: The service is automatically unregistered
  }

};

US_EXPORT_MODULE_ACTIVATOR(DictionaryServiceModule, MyActivator)
//![Activator]

#include <usModuleInitialization.h>

US_INITIALIZE_MODULE("DictionaryServiceModule", "", "", "1.0.0")

The launcher loads module A and try to use its service (ref is not found)

/*
 * main.cpp
 *
 *  Created on: 7 mai 2012
 *      Author: simon
 */

#include<vector>
#include<algorithm>
#include <iostream>
#include <usModuleActivator.h>
#include <usModuleContext.h>
#include "usTestUtilSharedLibrary.cpp"
#include "DictionaryService.h"

US_USE_NAMESPACE

/**
 * This class implements a module activator that uses the module
 * context to register an English language dictionary service
 * with the C++ Micro Services registry during static initialization
 * of the module. The dictionary service interface is
 * defined in a separate file and is implemented by a nested class.
 */
class US_ABI_LOCAL MyActivator: public ModuleActivator {

public:

	/**
	 * Implements ModuleActivator::Load(). Registers an
	 * instance of a dictionary service using the module context;
	 * attaches properties to the service that can be queried
	 * when performing a service look-up.
	 * @param context the context for the module.
	 */
	void Load(ModuleContext* context) {
		std::cout << "Hello World" << std::endl;
	}

	/**
	 * Implements ModuleActivator::Unload(). Does nothing since
	 * the C++ Micro Services library will automatically unregister any registered services.
	 * @param context the context for the module.
	 */
	void Unload(ModuleContext* /*context*/) {
		// NOTE: The service is automatically unregistered
	}

};

US_EXPORT_MODULE_ACTIVATOR(MainModule, MyActivator)
//![Activator]

#include <usModuleInitialization.h>
US_INITIALIZE_MODULE("MainModule", "", "", "1.0.0")

using namespace std;
int main(int /*argc*/, char* /*argv*/[]) {

	SharedLibraryHandle libA("DictionaryServiceModule"
#ifndef US_BUILD_SHARED_LIBS
			, _us_module_activator_instance_DictionaryServiceModule
#endif
			);
	libA.Load();

	vector<Module*> modules;
	GetModuleContext()->GetModules(modules);

	for (auto it = modules.begin(); it != modules.end(); ++it) {
		cout << (*it)->GetName() << endl;
	}

	Module* moduleA = ModuleRegistry::GetModule("DictionaryServiceModule");

	if (moduleA) {

		cout << moduleA->IsLoaded() << endl;
	} else {
		cout << "errrrrrrror" << endl;
	}

	auto refs = GetModuleContext()->GetServiceReferences("");
	for (auto it = refs.begin(); it != refs.end(); ++it) {
		cout << (*it).GetProperty(ServiceConstants::OBJECTCLASS()) << endl;
	}

	//![GetDictionaryService]
	ServiceReference dictionaryServiceRef =
			GetModuleContext()->GetServiceReference("foo");
	if (dictionaryServiceRef) {
		DictionaryService* dictionaryService = (DictionaryService*) GetModuleContext()->GetService(dictionaryServiceRef);
		if (dictionaryService) {
			std::cout << "Dictionary contains 'Tutorial': "
					<< dictionaryService->checkWord("Tutorial") << std::endl;
		}
	}

	return 0;
}

Build script

#!/bin/bash

US_ROOT=${HOME}/Workspace/ReflectionCpp/CppMicroServices
US_LIB=${US_ROOT}/lib/libCppMicroServices.so
US_INCLUDE=${US_ROOT}/include/
OPTS="-std=c++0x  -rdynamic"

g++ ${OPTS} -I${US_INCLUDE}   -fPIC  -c src/DictionaryModule.cpp -o DictionaryServiceModule.o
g++ ${OPTS} -I${US_INCLUDE}   -shared  -o libDictionaryServiceModule.so DictionaryServiceModule.o
g++ ${OPTS} -I${US_INCLUDE} -c src/main.cpp -o main.o
g++ ${OPTS} -L/usr/local/lib/  main.o  -o testApp -lCppMicroServices -ldl

Output:

$ LD_LIBRARY_PATH="/usr/local/lib/:." ./testApp 
Hello World
CppMicroServices
MainModule
DictionaryServiceModule
1
get service ref foo for module MainModule = 0 refs

Thanks again!

#7 Bug Reports » System install & usConfig » 2012-05-07 17:11:42

simon
Replies: 2

Hi,

Currently when doing a system install (cmake . && make install) on a *nix system, the usConfig.h file is not copied to /usr/local/include.

Is this planned, i.e are users supposed to copy this file to their own modules, or just an oversight?

#8 Re: General Discussions & Feedback » Running a simple example » 2012-05-07 17:05:57

I had it pinned down to the fact that the activator symbol wasn't found (registering the service immediately in main()) but I did not know about this linking option. It now works perfectly :-).

And yes, a project generator would likely have saved me here.

Thanks a lot!

#9 General Discussions & Feedback » Running a simple example » 2012-05-07 16:04:16

simon
Replies: 2

Hi,

I am trying to build the Dictionary snippet and run it outside of CppMicroServices' build as an exercice to make an external module.

I can run the executable built by CppMicroServices' build just fine -- and the Dictionary service is found.
Here's the normal output.

$ ./uServices-dictionaryservice 
get service ref DictionaryService/1.0 for module DictionaryServiceModule = 1 refs
Dictionary contains 'Tutorial': 1

Now, I have taken the snippet out and trying to make a very simple build out of it.
Here's my build script:

#!/bin/bash

US_ROOT=${HOME}/Workspace/ReflectionCpp/CppMicroServices
US_LIB=${US_ROOT}/lib/libCppMicroServices.so
US_INCLUDE=${US_ROOT}/include/
OPTS="-std=c++0x"


g++ ${OPTS} -I${US_INCLUDE} -c src/main.cpp -o main.o
g++ -L/usr/local/lib/ main.o -o testApp -lCppMicroServices

It builds just fine, but when running it the Dictionary service is *not* found:

$ LD_LIBRARY_PATH=/usr/local/lib/ ./testApp 
get service ref DictionaryService/1.0 for module DictionaryServiceModule = 0 refs

The Load(ModuleContext*) method of the Activator is not even called (I made sure by adding a log on stdout there).

What am I missing?

Cheers,
Simon

#10 Feature Requests » Minimal module template generator » 2012-05-07 15:50:12

simon
Replies: 1

Idea to help getting started quickly:

I think a very useful tool would be a simple module template generator, a bit similar to Maven archetypes.

The generator (a script?) would ask for a module/project name, find Cpp Micro Services' install (or ask the users its location) and generate a CMake build, an activator, and a simple test layout.

I know nothing of CMake (yet) and so I don't think I could help here, but it would definitely be a big help.

Board footer

Powered by FluxBB