I want to create two domain participant with two qos file. One for one participant.
I try but I don't succes very well...
First Step, I create the two domain like this :
DomainParticipantManager::createParticipant(1, _T("PLOP_QOS_FILE.xml"));
DomainParticipantManager::createParticipant(2, _T("PLIP_QOS_FILE.xml"));
DomainParticipantManager is like this :
void DomainParticipantManager::createParticipant(int domainId, const CString & qosFile)
{
DDSDomainParticipant * domainParticipant = NULL;
for (int index = 0; index < m_CountDDSDomainParticipant; index++)
{
DDSDomainParticipant * tmpDDSParticipant = m_TabDDSDomainParticipant[index];
if (tmpDDSParticipant->get_domain_id() == domainId)
{
domainParticipant = tmpDDSParticipant;
}
}
if (domainParticipant == NULL)
{
/* To load my_custom_qos_profiles.xml, as explained above, we need to modify
* the DDSTheParticipantFactory Profile QoSPolicy */
DDS_DomainParticipantFactoryQos factory_qos;
DDSTheParticipantFactory->get_qos(factory_qos);
/* We are only going to add one XML file to the url_profile sequence, so we
* ensure a length of 1,1. */
factory_qos.profile.url_profile.ensure_length(1, 1);
/* The XML file will be loaded from the working directory. That means, you
* need to run the example like this:
* ./objs/<architecture>/profiles_publisher
* (see README.txt for more information on how to run the example).
*
* Note that you can specify the absolute path of the XML QoS file to avoid
* this problem.
*/
factory_qos.profile.url_profile[0] =
DDS_String_dup(qosFile); //"TEST_QOS_FILE.xml");
DDSTheParticipantFactory->set_qos(factory_qos);
/* Our default Qos profile, volatile_profile, sets the participant name.
* This is the only participant_qos policy that we change in our
* example. As this is done in the default QoS profile, we don't need
* to specify its name, so we can create the participant using the
* create_participant() method rather than using
* create_participant_with_profile(). */
/*participant = DDSTheParticipantFactory->create_participant(
domainId, DDS_PARTICIPANT_QOS_DEFAULT,
NULL, DDS_STATUS_MASK_NONE);
if (participant == NULL) {
printf("create_participant error\n");
publisher_shutdown(participant);
return -1;
}*/
domainParticipant = DDSTheParticipantFactory->create_participant(
domainId,
DDS_PARTICIPANT_QOS_DEFAULT,
NULL /* listener */,
DDS_STATUS_MASK_NONE);
DDSDomainParticipant ** newTableau = new DDSDomainParticipant*[m_CountDDSDomainParticipant + 1];
for (int index = 0; index < m_CountDDSDomainParticipant; index++)
{
newTableau[index] = m_TabDDSDomainParticipant[index];
}
newTableau[m_CountDDSDomainParticipant] = domainParticipant;
m_CountDDSDomainParticipant++;
delete[] m_TabDDSDomainParticipant;
m_TabDDSDomainParticipant = newTableau;
}
else
{
printf("warning : domain %d already initialized !\n", domainId);
}
//return domainParticipant;
}
The second step is simple :
//Creation des publishers
m_pTopicPP = new TopicPPPublisher(
1,
_T("EXT"),
_T("P_P_Library"),
_T("P_P_Publisher_Profile"),
_T("P_P_Writer_Qos"));
//Creation des publishers
m_pTopicTX = new TopicTXPublisher(
2,
_T("INT"),
_T("T_X_Library"),
_T("T_X_Publisher_Profile"),
_T("T_X_Writer_Qos"));
The result is like the second call of DomainParticipantManager::createParticipant erase the first call. So My Qos Factory don't containt the first file.
Maybe it is because I execute "factory_qos.profile.url_profile[0] =
DDS_String_dup(qosFile); //"TEST_QOS_FILE.xml");" and I should do something like this :
factory_qos.profile.url_profile[m_CountDDSDomainParticipant] =
DDS_String_dup(qosFile); //"TEST_QOS_FILE.xml"); but int this case, how can I says at DDSTheParticipantFactory to select the first url and not the second in this line of code : domainParticipant = DDSTheParticipantFactory->create_participant(
domainId,
DDS_PARTICIPANT_QOS_DEFAULT,
NULL /* listener */,
DDS_STATUS_MASK_NONE);
What sould I wrote to replace "DDS_PARTICIPANT_QOS_DEFAULT" ?
Thank you very much !
Maxime
Hello Potoman,
The DomainParticipantFactory is a singleton class, so every time you set and get its QoS you are operating over the same object. As a result, when you call
factory->set_qos(factory_qos)
you are actually overwriting the value of the differenturl_profile
sequence with your new QoS file. To add a new file instead of overwriting the value of whatever was in there, you will need to add new elements to the sequence every time you want to add a new XML file with new QoS definitions.This is more or less what I would in your
createParticipant()
function to be able to load more than one QoS file:Now if you want to create DomainParticipants with different QoS profiles you will need to create in your XML files different QoS profiles in different QoS libraries that you will need to specify when creating your participant. To specify an specific QoS profile when you create the participant you will need to call the
DDSDomainParticipantFactory::create_participant_with_profile()
method. I would change your function to pass the name of the library and QoS profile.Let me know if this works for you.
Best regards,
Fernando.
Thank Fernando.
I already know what you say so let me tell you what I actually want to do...
Very sorry if I don't speak with a really good english by advance so I try to make short sentence with easy word :)
I want, when a user wish create a DomainParticipant, affect this domain with one (or more) specific Qos file. So when he want create participant with a specific profile, he only have the choice among the profil are in the Qos affected by the domain Id.
By example:
I have three Qos file :
Qos file A, B and C.
In Qos file A, I have profil a, b, c.
In Qos file B, I have profile d.
And finally, in Qos file C, I have profil e and f.
My question is : Can I instanciate a DomainParticipant with a DomainParticipantFactory init with Qos file A & B that allow this DomainParticipant to use the profil a, b, c and d.
And after, reset the Qos File in the DomainParticipantFactory by init it with Qos file C in front to create another DomainParticipant that allow the user to only use the profil e and f ?
The Qos File can be link with a DomainParticipant after the creating of the DomainParticipant And not only link with DomainParticipantFactory ?
Thanks.
Because if we can't link different QOS file with different DomainParticipant... WHY !!! Yes WHY !!! Why we specific the value "DomainParticipantFactory.PARTICIPANT_QOS_DEFAULT" in the call to create a DomainParticipant.
Cf :
DomainParticipantFactory.TheParticipantFactory.create_participant(domainId,
DomainParticipantFactory.PARTICIPANT_QOS_DEFAULT,
null,
StatusKind.STATUS_MASK_NONE));
Me, I want to do :
DomainParticipantFactory.TheParticipantFactory.create_participant(1,
QosFileA,
null,
StatusKind.STATUS_MASK_NONE));
DomainParticipantFactory.TheParticipantFactory.create_participant(2,
QosFileB & QosFileC,
null,
StatusKind.STATUS_MASK_NONE));
Is it possible ?
Thanks.
Hello Potoman,
When you create a DomainParticipant you are creating an entity that will interact with other DomainParticipants within the same domain. You can have many different DomainParticipants within the same domain with different QoS profiles. Each of these DomainParticipants needs to be created with an specific QoS profiles. If its profile is not specified (i.e., if you pass the PARTICIPANT_QOS_DEFAULT), the middleware will decide what is the default QoS profile in your case.
I have some doubts of what you intent to create when you pass an XML file to the DomainParticipantFactory to create a DomainParticipant. In DDS, you have to specify the QoS profile you want to create your participant with. XML files you may load are just containers where these QoS profiles are stored. In other words, all your profiles (i.e., a, b, c, d, and e) could be in the same XML file--it will not make a different in the end.
Once you have written all the QoS profiles that you want your different participants to use, you need to load them. To load them you need to add them to a sequence of files to be loaded, which is contained in the DomainParticipantFactoryQoS (i.e., factory_qos.profile.url_profile). You will find how to do this in my previous answer. Once they are loaded and available, you need to explicitly specify the profile you want to create your participant with. DomainParticipants can only be created with one QoS profiles. If you want to use another QoS profile, you will need to create a different participant within the same domain.
In summary, what you want to achieve is not possible. You can only create a DomainParticipant with a single QoS profile (regardless of whether is the default one or any of the other available ones). If you give us more detail about your use case, we will try to find a workaround to achieve what you want.
Thanks,
Fernando.