Loading user XML QoS Profiles in C++

6 posts / 0 new
Last post
Offline
Last seen: 1 year 7 months ago
Joined: 05/20/2015
Posts: 11
Loading user XML QoS Profiles in C++

Hey guys,

I'm not able to get XML QoS files to load in modern C++.  We are using version 5.2.3.  These work perfectly fine while using the C# APIs.  In trying to find a workaround, I found that the XML also will not load if I put it in either $NDDSHOME/resource/xml/NDDS_QOS_PROFILES.xml or <working directory>/USER_QOS_PROFILES.xml.  I'm just using the sample code in the user manual almost verbatim.

auto qosParams = dds::core::QosProvider::Default()->default_provider_params();
std::vector<std::string> filePaths;
filePaths.push_back("file://avnsil_qos_library.xml");
qosParams.url_profile(filePaths);
dds::core::QosProvider::Default()->default_provider_params(qosParams); // <-- This throws a dds::core::Error and crashes the program with a memory error in the CRT

I can check the return from qosParams.url_profile() after I set it, and it looks fine, just like the string I input.  Is this a bug, or something I'm doing wrong?

Thanks!

Keywords:
Fernando Garcia's picture
Offline
Last seen: 4 months 6 days ago
Joined: 05/18/2011
Posts: 199

Hi Craig,

You can follow the example on using XML profiles that we posted on the RTI Connext DDS Examples GitHub repository.

To load an XML file with custom QoS defintiions, pass the path to the XML file to the constructor of the QosProvider and use it in the creation of the DomainParticipant. For example:

    // Retrieve QoS from custom profile XML and USER_QOS_PROFILES.xml
    QosProvider qos_provider("my_custom_qos_profiles.xml");

    // Create a DomainParticipant with the default QoS of the provider.
    DomainParticipant participant(domain_id, qos_provider.participant_qos());
Let me know if this works for you. You will find mor information on how to pass files and XML defintiions to the QosProvider in the online API documentation.
 
Thanks,
Fernando.
Offline
Last seen: 1 year 7 months ago
Joined: 05/20/2015
Posts: 11

Thanks Fernando, that's working a lot better for me.


I'm having another problem when I try to confirm that my library has loaded by using qos_profile_libraries().  The call works fine, but it causes the program to crash when exiting the scope of the QosProvider instance.  Simply adding the line "auto library_names = qos_provider->qos_profile_libraries();" causes the crash at the end of the scope, even though it returns the values I'm expecting it to.  I tried testing with a few other extension methods (QosProviderImpl) and some of them cause the same crash as well.  Do I need to do something specific to get those to work?

Thanks,

- Craig

 

Fernando Garcia's picture
Offline
Last seen: 4 months 6 days ago
Joined: 05/18/2011
Posts: 199

Hi Craig,

Can you post a snippet with the code that makes your application crash? I could not reproduce with a simple example like the following:

{                                                                                                                                                                                                                  
    // Qos Provider                                                                                                                                                                                                
    dds::core::QosProvider qos_provider("my_xml_file.xml");                                                                                                                                                        
                                                                                                                                                                                                                   
    // Create a DomainParticipant with default Qos                                                                                                                                                                 
    dds::domain::DomainParticipant participant (domain_id, qos_provider.participant_qos());                                                                                                                        
                                                                                                                                                                                                                   
    // Create a Topic -- and automatically register the type                                                                                                                                                       
    dds::topic::Topic topic (participant, "Example Hello");                                                                                                                                                 
                                                                                                                                                                                                                   
    // Create a DataWriter with default Qos (Publisher created in-line)                                                                                                                                            
    dds::pub::DataWriter writer(dds::pub::Publisher(participant), topic);                                                                                                                                   
                                                                                                                                                                                                                   
    auto library_names = qos_provider->qos_profile_libraries();                                                                                                                                                                                                                                                                                                                                                                       
}                                                                                                                                                                                                                  

Thanks,
Fernando.

Offline
Last seen: 1 year 7 months ago
Joined: 05/20/2015
Posts: 11

Good afternoon Fernando,

We've got a DataDistributionService class that handles the setup and management of our Participants, Publishers, Subscribers and Topics for each application.  This is in the constructor where we are creating these objects somewhat like your code in the previous post.  I can post the entire method if you would like to see it, but I've experimented with disabling combinations of everything in the method and nothing will make this qos_profile_libraries() call survive the method return.

I can reduce the entire constructor to two lines of code:

DataDistributionService(int domain_id, std::string participant_name)
{
    auto qos_provider = dds::core::QosProvider("../../../../dds_qos/avnsil_qos_library.xml", "AvnsilQosLibrary::AvnsilQosOverridesProfile");
    auto library_names = qos_provider->qos_profile_libraries();
}

and this crashes the program when the method returns. If I comment out the qos_profile_libraries() call, it doesn't crash. The crash is an assertion failed in the operator delete function of dbgdel.cpp:52 in the CRT (_BLOCK_TYPE_IS_VALID(pHead->nBlockUse).  So, some type of dynamic memory/heap issue, but I'm unsure how to debug this further.  You guys don't include debugging symbols for your code do you?  Is there another way to determine which QoS libraries have been loaded?

Also, would this be easier/quicker to solve via email?  We have an active maintenance/support contract.

Thanks!

Fernando Garcia's picture
Offline
Last seen: 4 months 6 days ago
Joined: 05/18/2011
Posts: 199

Hi Craig,

I couldn't reproduce with the simple secnario of your constructor. It might be some memory corruption problem. I tried a simple application like the following, combining it with the creation of entities and sample writting, but I did not have any luck.

...
 
class DataDistributionService {
public:
    DataDistributionService(int domain_id, std::string participant_name)
    {
        auto qos_provider = dds::core::QosProvider("my_xml_file.xml", "Hello_Library::Hello_Profile");
        auto library_names = qos_provider->qos_profile_libraries(); 
    } 
};

int main()
{
    try { 
        DataDistributionService dds_instance(0, "my_participant"); 
    } catch (const std::exception& e) {
        std::cerr << "Exception in main(): " << e.what() << std::endl;
        return 1;
    }
  
    return 0; 
}    

If you have an active support contract, you can email support@rti.com and they can help you with your problem. Also if you find the answer, please let us know in the forum so that we can learn what things could lead to this kind of problems.

Thanks,
Fernando.