Trap_receiver::notify_register() error: unresolved overloaded function

I am trying to create a basic TrapReciever and have been working with the code from snmp++ version 3.3.10. I have been looking at the file “…\consoleExamples\receiveTrap.cpp” and have modified it so that I may use it as a class object. However, I keep getting the error at the statement, status = snmp.notify_register(oidc, targetc, callback, NULL);

The compiler is telling me:

error: not matching function for call to 'snmp_pp::Snmp::notify_register(Snmp_pp::OidCollection&, Snmp_pp::TargetCollection&, <unresolved overloaded function type>, NULL)'
    status = snmp.notify_register(oidc, targetc, callback, NULL);
.........
.........
.........
.... Note: no known conversion for argument 3 from '<unresolved overloaded function type>' to 'Snmp_pp::snmp_callback {aka void (*)(int, Snmp_pp::Snmp*, Snmp_pp::Pdu&, Snmp_pp::SnmpTarget&, void*)  }'

Below is my simple code implementation taken from snmp++ 3.3.10 receive_trap.cpp. If you could help me understand what this error is tying to tell me and how to resolve it I would be greatly appreciative!

#include <libsnmp.h>

#include "snmp_pp/snmp_pp.h"
#include "snmp_pp/collect.h"
#include "snmp_pp/notifyqueue.h"

using namespace Snmp_pp;

class TrapTester{


    private:

    void callback(int reason, Snmp *snmp, Pdu &pdu, SnmpTarget &target, void *cd)
    {
    Vb nextVb;
    int pdu_error;
    GenAddress addr;

    target.get_address(addr);
    UdpAddress from(addr);

    std::cout << "reason: " << reason << std::endl
                << "msg: " << snmp->error_msg(reason) << std::endl
                << "from: " << from.get_printable() << std::endl;

    pdu_error = pdu.get_error_status();
    if (pdu_error){
        std::cout << "Response contains error: " 
        << snmp->error_msg(pdu_error)<< std::endl;
    }
    Oid id;
    pdu.get_notify_id(id);
    std::cout << "ID:  " << id.get_printable() << std::endl;
    std::cout << "Type:" << pdu.get_type() << std::endl;

    for (int i=0; i<pdu.get_vb_count(); i++)
    {
        pdu.get_vb(nextVb, i);
        std::cout << "Oid: " << nextVb.get_printable_oid() << std::endl
                 << "Val: " <<  nextVb.get_printable_value() << std::endl;
    }
    if (pdu.get_type() == sNMP_PDU_INFORM) {
        std::cout << "pdu type: " << pdu.get_type() << std::endl;
        std::cout << "sending response to inform: " << std::endl;
        nextVb.set_value("This is the response.");
        pdu.set_vb(nextVb, 0);
        snmp->response(pdu, target);
    }
    std::cout << std::endl;
    }


    TrapTester(){

        createTrapRcvr();
    }

    void createTrapRcvr()
    {
    int trap_port;
    trap_port = 16200;
    //----------[ create a SNMP++ session ]-----------------------------------
    int status; 
    Snmp::socket_startup();  // Initialize socket subsystem
    Snmp snmp(status);                // check construction status
    if (status != SNMP_CLASS_SUCCESS)
    {
        std::cout << "SNMP++ Session Create Fail, " << snmp.error_msg(status) << "\n";
        return 1;
    }

    v3MP *v3_MP = Snmp_p::v3MP::I;

    USM *usm = v3_MP->get_usm();

    usm->add_usm_user("user",)

    // testusers
    usm->add_usm_user("unsecureUser",
                SNMP_AUTHPROTOCOL_NONE, SNMP_PRIVPROTOCOL_NONE, 
                "", "");
                
    OidCollection oidc;
    TargetCollection targetc;

    std::cout << "Trying to register for traps on port " << trap_port << "." << std::endl;
    snmp.notify_set_listen_port(trap_port);
    status = snmp.notify_register(oidc, targetc, callback, NULL);
    if (status != SNMP_CLASS_SUCCESS)
    {
        std::cout << "Error register for notify (" << status << "): "
        << snmp.error_msg(status) << std::endl;
        exit(1);
    }
    else
        std::cout << "Waiting for traps/informs..." << std::endl;


    snmp.start_poll_thread(1000);

    std::cout << "press return to stop\n";
    getc(stdin);

    snmp.stop_poll_thread();

    Snmp::socket_cleanup();  // Shut down socket subsystem
    }
    


}

I think the callback cannot be a private member of your class.

I’ve tried both private and public. From what I’ve found is that the call back may not be a non-static member function. I’m not really sure the implications of making the callback static since there will only be one trap receiver on this application I’d imagine it would be fine.

I’ve played around with it a bit and came up with a bit of a hybrid approach that uses the static callback to handle the incoming messages. This callback will then determine what method to process the message with by extracting its oid.

Is this a sufficient implementation and am I using *callback_data argument for notify_register correctly. It seems to build fine, but I haven’t been able to sufficiently test it yet.

void createTrapRcvr(){
...
...
...
    TrapTester* tt = this;
    void (*callback_prt)(int, Snmp*, Pdu&, SnmpTarget&, void*) = &TrapTester::static_my_callback;
    OidCollection Oidc;
    TargetCollection targetc;
    snmp.notify_set_listen_port(trap_port);
    status= snmp.notify_register(oidc, targetc, callback_ptr, tt);

...
...
...
}

static void static_my_callback(int reason, Snmp *snmp, Pdu &pdu, SnmpTarget &target, void *cd){

    TrapTester* tt = static_cast<TrapTester*>(cd);
/*
/Do logic for handling specific trap cases
/      switch(oid.get_printable){
/           case CONST_OID_CASE1:
/           tt->oidCase1Callback(reason,snmp,pdu,target,cd);
/           break;
}
*/
}

void oidCase1Callback(int reason, Snmp *snmp, Pdu &pdu, SnmpTarget &target, void *cd){
   /*
   / Process the message and send it to the rest of the system
  */
}