1

Those @things are EmPy

C++

  const char *
  publish__@(spec.base_type.type)(void * untyped_data_writer, const void * untyped_message)
  {
    DataWriter * topic_writer = static_cast<DataWriter *>(untyped_data_writer);
    const __ros_msg_type & ros_message = *(const __ros_msg_type *)untyped_message;
    __dds_msg_type dds_message;
    conversion_cpp(ros_message, dds_message);

    @(__dds_msg_type_prefix)DataWriter * data_writer =
      @(__dds_msg_type_prefix)DataWriter::_narrow(topic_writer);
    DDS::ReturnCode_t status = data_writer->write(dds_message, DDS::HANDLE_NIL);

    // some common switch statements in C and C++

    }
  }

C

static const char *
publish(void * data_writer, const void * cool_message)
{
  if (!data_writer) {return "data writer handle is null";}
  if (!cool_message) {return "ros message handle is null";}

  DDS::DataWriter * topic_writer = static_cast<DDS::DataWriter *>(data_writer);
  __dds_msg_type dds_message;
  const char * err_msg = conversion_c(cool_message, &dds_message);
  if (err_msg != 0) {return err_msg;}

  @(__dds_msg_type_prefix)DataWriter * data_writer =
    @(__dds_msg_type_prefix)DataWriter::_narrow(topic_writer);
  DDS::ReturnCode_t status = data_writer->write(dds_message, DDS::HANDLE_NIL);
@[for field in spec.fields]@
@[if field.type.type == 'string']@
@[if field.type.is_array]@
  {
@[if field.type.array_size]@
    size_t size = @(field.type.array_size);
@[else]@
    size_t size = dds_message.@(field.name)_.length();
@[end if]@
    for (DDS::ULong i = 0; i < size; ++i) {
      // This causes the DDS::String_mgr to release the given c string without freeing it.
      dds_message.@(field.name)_[i]._retn();
    }
  }
@[else]@
  // This causes the DDS::String_mgr to release the given c string without freeing it.
  dds_message.@(field.name)_._retn();
@[end if]@
@[end if]@
@[end for]@

  // some common switch statements in C and C++
  }
}

This question is a bit specific to an open source project I am trying to contribute to, so I ll point to the exact functions I guess. This is the original C method and this is the C++ method

Do I need to use function pointers?
Another thing going on here is that the C package depends on the C++ package.

(Maybe this isn't good question or is a vague question, but I am not sure what to do as I am new to this codebase)

madratman
  • 127
  • 2
  • 8
  • 2
    Please post the simplified relevant code here. – Mohit Jain Feb 29 '16 at 06:15
  • That "C" function looks to me like it is written in C++, while the "C++" function is written as though in C (`void*` arguments, yuk). Do you mean that the first one is declared `extern "C"` or some such? I didn't penetrate the template metacharacters but it wasn't at all obvious why you need two different functions at all. Maybe you could clarify what the difference is. And what might any of this have to do with function pointers? – rici Feb 29 '16 at 06:36
  • Yes, it is extern C, look at the C method's link in the post or [here](https://github.com/ros2/rmw_opensplice/blob/master/rosidl_typesupport_opensplice_c/resource/msg__type_support_c.cpp.template#L59) The purpose is slightly involved, I can point you to [this link](http://design.ros2.org/articles/ros_middleware_interface.html). It's basically generating message files for DDS to be used either with a C or C++ client library. Man I should ask the maintainers, I am slightly confused at this point. Maybe, it's overengineering – madratman Feb 29 '16 at 06:46
  • @madratman: There's not a lot of point putting `#if defined(__cplusplus) / extern "C" {` before code which uses `static_cast`. It won't compile unless you're using a C++ compiler, so the `ifdef` is redundant. Unless there is something not immediately visible to me. And I still think that using `void*` arguments for a C++ function is yuk. (It's yuk in C, too, but sometimes it is necessary.) But I suppose they had their reasons. – rici Feb 29 '16 at 06:58
  • "extern "C" makes a function-name in C++ have 'C' linkage (compiler does not mangle the name) so that client C code can link to (i.e use) your function using a 'C' compatible header file that contains just the declaration of your function. Your function definition is contained in a binary format (that was compiled by your C++ compiler) that the client 'C' linker will then link to using the 'C' name." [source](http://stackoverflow.com/questions/1041866/in-c-source-what-is-the-effect-of-extern-c) – madratman Feb 29 '16 at 07:13
  • As I said in prev msg, "It's basically generating message files for DDS to be used either with a C or C++ client library" " What this accomplishes is that it allows you to use that C header file with your C++ code, because the macro "__cplusplus" will be defined. But you can also still use it with your legacy C code, where the macro is NOT defined, so it won't see the uniquely C++ construct." [source](http://stackoverflow.com/questions/1041866/in-c-source-what-is-the-effect-of-extern-c) – madratman Feb 29 '16 at 07:14
  • I see it now. My question's wording might be misleading. – madratman Feb 29 '16 at 07:16

0 Answers0