Helloworld example for C ?? PreviousNext
Data Distribution Service (DDS) Forum > DDS FAQ >
Message/Author
Next message Devin Butterfield  posted on Wednesday, November 07, 2007 - 06:28 pm
Hi,

Sorry, I first accidentally posted this under a different thread...

I have seen the Helloworld example for C++ on the omg website: http://portals.omg.org/dds/HelloWorldApplication but I would be very interested to see a helloworld for C. Can someone who is familiar with a C implementation of DDS post a simple helloworld example?

Thanks!
--
Regards, Devin
Next message Erik Hendriks  posted on Thursday, November 08, 2007 - 01:26 pm
Hi Devin,

I'll try to give the same example written in C, but please be aware that the exact notation of the resulting C code may be vendor specific.

Let's assume the same IDL model: the C language representation of such a model will also look like this:

typedef struct HelloWorld HelloWorld ;
struct HelloWorld {
DDS_string name;
DDS_string msg;
}

The exact appearance of this code may be vendor specific, but the way you access this data in your application code should be indentical for each vendor.

Also for the API there are some implementor specific things. For example: the DDS spec intentionally allows the domainId type to be vendor specific. But also the header files your application needs to include are vendor specific.

The code fragments below are based on the OpenSplice DDS implementation of the DCPS.

The Publisher:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // needed for sleep()

#include <dds_dcps.h>
#include "HelloWorld.h"

int main(int argc, char *argv[])
{
DDS_DomainId_t domainId = NULL;
int sample_count = 100;
DDS_DomainParticipant participant = NULL;
DDS_Publisher publisher = NULL;
DDS_Topic topic = NULL;
HelloWorldTypeSupport helloWorldTS = NULL;
HelloWorldDataWriter helloWriter = NULL;
HelloWorld instance;
DDS_InstanceHandle_t instance_handle = DDS_HANDLE_NIL;
const char *type_name = NULL;
int count = 0;

participant = DDS_DomainParticipantFactory_create_participant(DDS_TheParticipantFactory,
domainId, DDS_PARTICIPANT_QOS_DEFAULT, NULL /* listener */,
0);

publisher = DDS_DomainParticipant_create_publisher(
participant, PUBLISHER_QOS_DEFAULT, NULL /* listener */,
0);

helloWorldTS = HelloWorldTypeSupport__alloc();
type_name = HelloWorldTypeSupport_get_type_name(helloWorldTS);
HelloWorldTypeSupport_register_type(
helloWorldTS, participant, type_name);

topic = DDS_DomainParticipant_create_topic(
participant, "Example_HelloWorld",
type_name, DDS_TOPIC_QOS_DEFAULT, NULL /* listener */,
0);

helloWriter = DDS_Publisher_create_datawriter(
publisher, topic, DDS_DATAWRITER_QOS_DEFAULT, NULL /* listener */,
0);

strcpy(instance.name, "MyName");
instance_handle = HelloWorldDataWriter_register_instance(helloWriter, instance);

/* Main loop */
for (count=0; (sample_count == 0) || (count < sample_count); ++count) {
sprintf(instance.msg, "Hello World! (count %d)", count);
printf("Writing: %s", instance.msg);
helloWriter->write(*instance, instance_handle);
sleep(1);
}

DDS_DomainParticipant_delete_contained_entities(participant);
DDS_DomainParticipantFactory_delete_participant(DDS_TheParticipantFactory, participant);
}

And finally the Subscriber:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // needed for sleep()

#include <dds_dcps.h>
#include "HelloWorld.h"


/* Listener used to receive notifications on data updates */
void on_HelloWorldData_available (
void *listener_data,
DDS_DataReader reader )
{
HelloWorldDataReader HelloWorld_reader = NULL;
DDS_sequence_HelloWorld *data_seq = NULL;
DDS_SampleInfoSeq *info_seq = NULL;

HelloWorld_reader = reader;
data_seq = DDS_sequence_HelloWorld__alloc();
info_seq = DDS_SampleInfoSeq__alloc();
retcode = HelloWorldDataReader_take(
HelloWorld_reader, data_seq, info_seq, DDS_LENGTH_UNLIMITED,
DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE);

for (i = 0; i <data_seq->_length; ++i) {
if (info_seq->_buffer[i].valid_data) {
printf("From %s: %s\n", data_seq->_buffer[i].name, data_seq->_buffer[i].msg);
}
}

retcode = HelloWorldDataReader_return_loan(HelloWorld_reader, data_seq, info_seq);
}

int main(int argc, char *argv[])
{
DDS_DomainId_t domainId = NULL;

DDS_DomainParticipant participant = NULL;
DDS_Subscriber subscriber = NULL;
DDS_Topic topic = NULL;
HelloWorldTypeSupport helloWorldTS = NULL;
struct DDS_DataReaderListener *reader_listener = NULL;
DDS_DataReader reader = NULL;
DDS_ReturnCode_t retcode;
const char *type_name = NULL;


participant = DDS_DomainParticipantFactory_create_participant(
DDS_TheParticipantFactory, domainId,
DDS_PARTICIPANT_QOS_DEFAULT, NULL /* listener */, 0);

subscriber = DDS_DomainParticipant_create_subscriber(
participant, DDS_SUBSCRIBER_QOS_DEFAULT, NULL /* listener */, 0);

helloWorldTS = HelloWorldTypeSupport__alloc();
type_name = HelloWorldTypeSupport_get_type_name(helloWorldTS);
retcode = HelloWorldTypeSupport_register_type(
helloWorldTS, participant, type_name);

topic = DDS_DomainParticipant_create_topic(
participant, "Example_HelloWorld",
type_name, DDS_TOPIC_QOS_DEFAULT, NULL /* listener */,
0);

/* Create data reader listener */
reader_listener = DDS_DataReaderListener__alloc();
reader_listener->listener_data = NULL;
reader_listener->on_data_available = (void (*)(void *, DDS_DataReader)) on_HelloWorldData_available;
reader_listener->on_requested_deadline_missed = NULL;
reader_listener->on_requested_incompatible_qos = NULL;
reader_listener->on_sample_rejected = NULL;
reader_listener->on_liveliness_changed = NULL;
reader_listener->on_subscription_matched = NULL;
reader_listener->on_sample_lost = NULL;

reader = DDS_Subscriber_create_datareader(
subscriber, topic, DDS_DATAREADER_QOS_DEFAULT, reader_listener,
DDS_DATA_AVAILABLE_STATUS);

/* Main loop. Does nothing. Action taken in listener */
for (count=0; (sample_count == 0) || (count < sample_count); ++count) {
printf("HelloWorld subscriber sleeping for %d sec...\n",
receive_period.sec);
sleep(10);
}

DDS_DomainParticipant_delete_contained_entities(participant);
DDS_DomainParticipantFactory_delete_participant(DDS_TheParticipantFactory, participant);
}
Next message Erik Hendriks  posted on Thursday, November 08, 2007 - 01:31 pm
My apologies for the layout: it seems the text is interpreted as HTML and therefore the indents are removed.

Regards,
Erik Hendriks.
Next message Erik Hendriks  posted on Thursday, November 08, 2007 - 01:35 pm
Finally, I forgot to release the sequences used in the Listener callback, resulting in a memory leak. Please add the following 2 lines right after the return_loan operation:

DDS_free(data_seq);
DDS_free(info_seq);

Regards,
Erik Hendriks.
Next message Erik Hendriks  posted on Thursday, November 08, 2007 - 01:58 pm
I noticed another error:

When passing a sample to the DataWriter it must be passed as a pointer. So the register_instance instruction and the write instruction should be like this:

instance_handle = HelloWorldDataWriter_register_instance(helloWriter, &instance);


HelloWorldDataWriter_write(helloWriter, &instance, instance_handle);

Sorry for the inconvenience. It seems the Preview button does not only provide a preview, but it also posts the message immediately.

Regards,
Erik.
Next message Devin Butterfield  posted on Friday, November 09, 2007 - 03:05 pm
Hi Erik,

That answered a lot of questions. Many thanks.
--
Regards, Devin
Next message Evgeni Sergeev  posted on Tuesday, January 15, 2008 - 02:55 am
I was wondering where does HelloWorldTypeSupport come from?

Evgeni
Next message Niels Kortstee  posted on Tuesday, January 15, 2008 - 06:56 am
Hi Evgeni,

Each DDS implementation provides an IDL compiler that translates the IDL type to language specific type, reader and writer.

For the IDL type 'HelloWorld', it generates the following language specific types (using the OMG IDL to language mapping):
- HelloWorld
- HelloWorldTypeSupport
- HelloWorldDataWriter
- HelloWorldDataReader

Best regards, Niels
Next message Evgeni Sergeev  posted on Thursday, January 17, 2008 - 04:15 am
Thanks Niels.

I added this information to the wiki page - since it <em>is</em> a HelloWorld program, it is probably relevant.
Back to top
Add Your Message Here
Post:
Username: Posting Information:
This is a private posting area. Only registered users and moderators may post messages here.
Password:
Options: Post as "Anonymous"
Enable HTML code in message
Automatically activate URLs in message
Action: