Get data writers from XML participant

4 posts / 0 new
Last post
ilya_1725's picture
Offline
Last seen: 1 month 1 week ago
Joined: 04/20/2020
Posts: 21
Get data writers from XML participant

We are using the XML profiles. This example shows how to create a particiant and get data writer:

 

int publisherMain(int sampleCount) {
    DDS_ReturnCode_t retCode;
    int count = 0;  
    DDS_Duration_t sendPeriod = {4,0};

    /* type registration */
    retCode = DDSTheParticipantFactory->register_type_support( HelloWorldTypeSupport::register_type, "HelloWorldType");
    if (retCode != DDS_RETCODE_OK) {
        fprintf(stderr, "register_type_support %d\n", retCode);
        publisherShutdown(NULL);
        return -1;
    }
    
    /* To customize participant QoS, use 
       the configuration file USER_QOS_PROFILES.xml */   
    DDSDomainParticipant * participant = DDSTheParticipantFactory->create_participant_from_config("MyParticipantLibrary::PublicationParticipant");
    if (participant == NULL) {
        fprintf(stderr, "create_participant_from_config error\n");
        publisherShutdown(participant);
        return -1;
    }
    
    HelloWorldDataWriter * helloWorldWriter = HelloWorldDataWriter::narrow( participant->lookup_datawriter_by_name("MyPublisher::HelloWorldWriter"));    
    if (helloWorldWriter == NULL) {
        fprintf(stderr, "lookup_datawriter_by_name error\n");
        publisherShutdown(participant);
        return -1;
    }
    
    HelloWorld * helloWorldData = HelloWorldTypeSupport::create_data();   
    if (helloWorldData == NULL) {
        fprintf(stderr, "HelloWorldTypeSupport_create_data error\n");
        publisherShutdown(participant);
        return -1;
    }
            
    /* Main loop */
    for (count=0; (sampleCount == 0) || (count < sampleCount); ++count) {
        printf("Writing HelloWorld, count: %d\n", count);
        fflush(stdout);

        /* Set the data fields */
        strncpy(helloWorldData->sender,  "John Smith", MAX_NAME_LEN); 
        strncpy(helloWorldData->message, "Hello World!", MAX_MSG_LEN); 
        helloWorldData->count   = count; 

        retCode = helloWorldWriter->write(*helloWorldData, DDS_HANDLE_NIL);
        if (retCode != DDS_RETCODE_OK) {
            fprintf(stderr, "write error %d\n", retCode);
            publisherShutdown(participant);
            return -1;
        }
        
        NDDSUtility::sleep(sendPeriod);
    }

    /* Delete data sample */
    HelloWorldTypeSupport::delete_data(helloWorldData);

    /* Delete all entities */
    return publisherShutdown(participant);
}

 

In our configuration the  "MyParticipantLibrary::PublicationParticipant" has more than one writer. Once the participant is created, it seems that all the writers are created as well - they show up in rtiadminconsole.

Do I still have to register_type_support for all types, specified in the participant configuration, I plan to use? Or I can just lookup_datawriter_by_name from the created participant?

 

Thank you.

 

 

Howard's picture
Offline
Last seen: 1 day 19 hours ago
Joined: 11/29/2012
Posts: 285

So, when using XML application creation, which is the "official" name not "xml profile" which can be confused with "QOS XML profile" which does not actually define DDS entities but only defines QOS configurations, then a good place to find documentation is here:

https://community.rti.com/static/documentation/connext-dds/6.0.1/doc/manuals/connext_dds/xml_application_creation/html_files/RTI_ConnextDDS_CoreLibraries_XML_AppCreation_GettingStarted/index.htm

So the datatypes used by the Topics in your application must all be registered with the DDSDomainParticipant before the Topics and associated DataWriters/DataReaders using the data types are created. 

This can be done in 2 ways...via XML or via source code, support for which is generated from IDL.  It seem that your code example is using datatype support code that was generated using rtiddsgen from the definition of the datatype.  In which case, your application code has to call DDSTheParticipantFactory->register_type_support or <datatype>TypeSupport::register_type directly before any Topics/DataWriters/DataReaders are created.

Another way is for datatypes to be defined in the XML file that's used to define the application.  For example

 

    <types>
        <const name="MAX_NAME_LEN" value="64" type="long"/>
	<const name="MAX_MSG_LEN" value="128" type="long"/>
	<struct name="HelloWorld">
		<member name="sender" type="string" 
		 stringMaxLength="MAX_NAME_LEN" key="true"/>
		<member name="message" type="string" 
		 stringMaxLength="MAX_MSG_LEN"/>
		<member name="count" type="long"/>	
	</struct>
    </types>

 

All datatypes defined in the XML file will be automatically registered when the participant is created from its definition in the XML file.  Which brings us to, when using DDSTheParticipantFactory->create_participant_from_config() to create a participant from its XML definition, ALL objects defined for that participant is create and exists at the time of creation of the participant. 

The method lookup_datawriter_by_name() is simply that, lookup and return an existing datawriter with that name.  It does not create the datawriter on invocation.

 

 

ilya_1725's picture
Offline
Last seen: 1 month 1 week ago
Joined: 04/20/2020
Posts: 21

Just to confirm: if I have the datatypes defined in the XML file that's used to define the application. Then call DDSTheParticipantFactory->create_participant_from_config(). Will all the readers and writers be created internally as well? And I can access to them by using lookup_datawriter_by_name()?

Howard's picture
Offline
Last seen: 1 day 19 hours ago
Joined: 11/29/2012
Posts: 285

Yup.