Search code examples
c++shared-ptr

boost shared pointer custom deleter example


I'm using the libmodbus library. i need to pass instances of the modbus_t pointer between threads. I am having difficulty with just raw pointers and I think i can solve the problem with using boost_shared_ptr with custom deleter.

i don't get any compiler issues but when i run the program it crashes. i was hoping if someone can give me a usage example of boost shared pointer with custom deleter.

the program crashes at line where m_mb.reset() is called the first time in the OpenModBusConnection() function.

m_mb = boost::shared_ptr<modbus_t>( modbus_new_rtu(m_heatercomport.c_str(),9600,'N',8,1), freemodbus);

    void freemodbus(modbus_t *mb)
    {
       if(mb != NULL)
       {
          modbus_close(mb);
          modbus_free(mb);      
       }
    }

    void OpenModBusConnection()
    {
        if(m_mb.get() != NULL)
        {           
            wxString msg("Closing port \"");
            msg.append(m_heatercomport);
            msg.append("\" modbus port ");
            wxLogMessage(msg);

            readoutput->AppendText("Modbus Connection Closed\n");

            m_mb.reset();

        }

        // open modbus connection
        m_mb.reset();
        modbus_set_slave(m_mb.get(),1);

        if(modbus_connect(m_mb.get()) == -1)
        {
            wxString msg("Failed to open port \"");
            msg.append(m_heatercomport);
            msg.append("\" modbus port ");
            wxLogMessage(msg);

            readoutput->AppendText("Modbus Connection Failed\n");

            return false;
        }
        else
        {
            wxString msg("Opening port \"");
            msg.append(m_heatercomport);
            msg.append("\" modbus port ");
            wxLogMessage(msg);

            readoutput->AppendText("Modbus Connection Established\n");

            return true;
        }
    }

error message i get is

First-chance exception at 0x7717bb47 in test.exe: 0xC0000008: An invalid handle was specified.

Solution

  • m_mb.reset();
    modbus_set_slave(m_mb.get(),1);
    
    if(modbus_connect(m_mb.get()) == -1)
    

    This is effectively the same as

    m_mb.reset();
    modbus_set_slave(nullptr,1);
    
    if(modbus_connect(nullptr) == -1)
    

    If you want to free and reset the m_mb back to a fresh modbus handle you need to do

    m_mb = boost::shared_ptr<modbus_t>( modbus_new_rtu(m_heatercomport.c_str(),9600,'N',8,1), freemodbus); 
    

    again expliticly.