ros2 / rosidl_typesupport

Packages which provide the typesupport for ROS messages and services
Apache License 2.0
13 stars 34 forks source link

expose symbol for cpp typesupport #32

Closed Karsten1987 closed 5 years ago

Karsten1987 commented 5 years ago

exposes a new symbol in the each message library in order to load the cpp typesupport.

rosidl_typesupport_cpp__get_message_type_support_handle__<pkg_name>__msg__<message_type>

This then allows to open the library (e.g. via Poco) and get the typesupport in order to create a ROS 2 publisher or subscriber:

#include <unistd.h>

#include "ament_index_cpp/get_resources.hpp"
#include "ament_index_cpp/get_package_prefix.hpp"

#include "Poco/SharedLibrary.h"

#include "rcl/rcl.h"

#include "rcutils/snprintf.h"

#include "rosidl_generator_c/message_type_support_struct.h"

std::string get_typesupport_library(const std::string & package_name)
{
  const char * env_var;
  char separator;
  const char * filename_prefix;
  const char * filename_extension;
#ifdef _WIN32
  env_var = "PATH";
  separator = ';';
  filename_prefix = "";
  filename_extension = ".dll";
#elif __APPLE__
  env_var = "DYLD_LIBRARY_PATH";
  separator = ':';
  filename_prefix = "lib";
  filename_extension = ".dylib";
#else
  env_var = "LD_LIBRARY_PATH";
  separator = ':';
  filename_prefix = "lib";
  filename_extension = ".so";
#endif

  auto package_prefix = ament_index_cpp::get_package_prefix(package_name);
  auto library_path = package_prefix + "/lib/" + filename_prefix + package_name + "__rosidl_typesupport_cpp" + filename_extension;
  fprintf(stderr, "package prefix for %s: %s\n", package_name.c_str(), package_prefix.c_str());
  fprintf(stderr, "full path to library: %s\n", library_path.c_str());

  return library_path;
}

int main(int argc, char ** argv)
{
  (void) argc;
  (void) argv;

  std::string type_name = "MyMessageType";
  std::string package_name = "my_message_type";

  auto library_path = get_typesupport_library(package_name);
  std::shared_ptr<Poco::SharedLibrary> typesupport_library = nullptr;
  const rosidl_message_type_support_t * ts = nullptr;

  try {
    typesupport_library = std::make_shared<Poco::SharedLibrary>(library_path);
    auto symbol_name = std::string("rosidl_typesupport_cpp__get_message_type_support_handle__")  + package_name + "__msg__" + type_name;
    fprintf(stderr, "sumbol name %s\n", symbol_name.c_str());
    if (!typesupport_library->hasSymbol(symbol_name)) {
      fprintf(stderr, "symbol not found %s\n", symbol_name.c_str());
      return -1;
    }
    fprintf(stderr, "symbol found\n");

    const rosidl_message_type_support_t * (*get_ts)(void) = nullptr;
    get_ts = (decltype(get_ts)) typesupport_library->getSymbol(symbol_name);
    ts = get_ts();
    if (!ts) {
      fprintf(stderr, "ts is null\n");
      return -1;
    }
    fprintf(stderr, "ts identifier %s\n", ts->typesupport_identifier);
  } catch (Poco::LibraryLoadException & e) {
    fprintf(stderr, "poco exception: %s\n", e.what());
  }

  return 0;
}
Karsten1987 commented 5 years ago

CI (testing only std_msgs):

linux: Build Status aarch: Build Status osx: Build Status win: Build Status