"No matching overloaded function" in ofEvent.h because I try to call ofRegisterURLNotification?

Why does adding ofRegisterURLNotification(this) to my ofApp::setup() cause ofEvent.h to fail with “no matching overloaded function”?

I’m trying to follow the instructions for receiving urlResponse events as shown in the only example I’ve found, here: https://openframeworks.cc/documentation/utils/ofURLFileLoader/#show_ofLoadURLAsync

I’ve followed all the steps, and am getting a compilation error in ofEvent.h line 535:
Error C2672 'ofEvent<ofHttpResponse,std::recursive_mutex>::addNoToken': no matching overloaded function found

The error goes away if I don’t do step 3: ofRegisterURLNotification(this); in ofApp::setup. However then when I actually make an Async call, the call happens but after a second or two I get an unhandled exception trying to create an event to an unallocated address.

I am trying to place an HTTP PUT with ofURLFileLoader::handleRequestAsync(), but so far it always throws an exception after doing the PUT, I’m guessing trying to fire an event that isn’t registered?

That is, I get:

Exception thrown: read access violation.
_Mtx_internal_imp_t::_get_cs(...)-> was 0xDDDDDDDD.

At mutex.c line 99.

Which further up the stack is in ofEvent.h line 479, higher up same file line 97, i.e. Function::notify()

My program manages to make an HTTP PUT just fine with nearly identical code using ofURLFileLoader::handleRequest() … but I don’t want to block until the requests I’m making return.

can you open a bug report on github?

Yes, will do.

@arturo I added two bug reports for those related issues on github. Tried in 0.11.0 with same result.

Then I tried to build for Android, and am getting a compiler problem when i try to add
ofRegisterURLNotification(this);
to ofApp:Setup().

Should I add another github bug report for this one?

In file included from C:\OF0.10.1And\apps\myApps\PrecisionFoodWorks\src\ofApp.cpp:1:
In file included from C:\OF0.10.1And\apps\myApps\PrecisionFoodWorks\src/Pages/../ofApp.h:3:
In file included from C:\OF0.10.1And\libs\openFrameworks\3d\../ofMain.h:11:
In file included from C:\OF0.10.1And\libs\openFrameworks\utils\ofURLFileLoader.h:3:
In file included from C:\OF0.10.1And\libs\openFrameworks\events\ofEvents.h:4:
In file included from C:\OF0.10.1And\libs\openFrameworks\events/ofEventUtils.h:4:
C:\OF0.10.1And\libs\openFrameworks\events\ofEvent.h:535:14: error: no matching member function for call to 'make_function'
                addNoToken(make_function(listener,method,priority));
                           ^~~~~~~~~~~~~
C:\OF0.10.1And\libs\openFrameworks\events/ofEventUtils.h:28:11: note: in instantiation of function template specialization 'ofEvent<ofHttpResponse, std::__ndk1::recursive_mutex>::add<ofApp, void (ofApp::*)(const ofHttpResponse &)>' requested here
    event.add(listener, listenerMethod, prio);
          ^
C:\OF0.10.1And\libs\openFrameworks\utils\ofURLFileLoader.h:100:2: note: in instantiation of function template specialization 'ofAddListener<ofEvent<ofHttpResponse, std::__ndk1::recursive_mutex>, const ofHttpResponse, ofApp>' requested here
        ofAddListener(ofURLResponseEvent(),obj,&T::urlResponse);
        ^
C:\OF0.10.1And\apps\myApps\PrecisionFoodWorks\src\ofApp.cpp:14:5: note: in instantiation of function template specialization 'ofRegisterURLNotification<ofApp>' requested here
    ofRegisterURLNotification(this);
    ^
C:\OF0.10.1And\libs\openFrameworks\events\ofEvent.h:490:14: note: candidate template ignored: failed template argument deduction
        FunctionPtr make_function(TObj * listener, void (TObj::*method)(const void*, T&), int priority){
                    ^
C:\OF0.10.1And\libs\openFrameworks\events\ofEvent.h:472:14: note: candidate template ignored: could not match 'bool' against 'void'
        FunctionPtr make_function(TObj * listener, bool (TObj::*method)(T&), int priority){
                    ^
C:\OF0.10.1And\libs\openFrameworks\events\ofEvent.h:477:14: note: candidate template ignored: could not match 'ofHttpResponse &' against 'const ofHttpResponse &'
        FunctionPtr make_function(TObj * listener, void (TObj::*method)(T&), int priority){
                    ^
C:\OF0.10.1And\libs\openFrameworks\events\ofEvent.h:485:14: note: candidate template ignored: could not match 'bool' against 'void'
        FunctionPtr make_function(TObj * listener, bool (TObj::*method)(const void*, T&), int priority){
                    ^
C:\OF0.10.1And\libs\openFrameworks\events\ofEvent.h:519:14: note: candidate function not viable: requires 2 arguments, but 3 were provided
        FunctionPtr make_function(std::function<void(const void*, T&)> f, int priority) {
                    ^
C:\OF0.10.1And\libs\openFrameworks\events\ofEvent.h:515:14: note: candidate function not viable: requires 2 arguments, but 3 were provided
        FunctionPtr make_function(std::function<void(T&)> f, int priority) {
                    ^
C:\OF0.10.1And\libs\openFrameworks\events\ofEvent.h:511:14: note: candidate function not viable: requires 2 arguments, but 3 were provided
        FunctionPtr make_function(std::function<bool(const void*, T&)> f, int priority) {
                    ^
C:\OF0.10.1And\libs\openFrameworks\events\ofEvent.h:507:14: note: candidate function not viable: requires 2 arguments, but 3 were provided
        FunctionPtr make_function(std::function<bool(T&)> f, int priority) {

Ok, I got some help for these from @roymacdonald , and I just had some errors in the way I was trying to do it, which he pointed out to me, and it seems to be working now, at least in my test program. I’ll be moving it to my actual application shortly to be sure, but hooray, and great thanks to Roy!!

1 Like

Would be nice to see how the correct solution looks like. Maybe if you have a moment you can share it with us ? :slight_smile:

Yes, I will share once I’ve confirmed I can get it all working without problems in Windows, Android and Mac. Hopefully in the next day or two.

Preview though is the exception was that, unlike when making a synchronous call, you need to keep the ofHttpRequest and ofURLFileLoader objects around until the response gets called, because ofURLFileLoader::handleRequestAsync() does not make copies of the ofHttpRequest you pass it. I had them as being local variables in the function that started the async call, so they went out of scope and got destroyed before the response.

And for the other bug that caused the enigmatic compiler error, I had the response handler as void ofApp::urlResponse(const ofHttpResponse & response) when it shouldn’t have had a const parameter - it needed to be void urlResponse(ofHttpResponse & response).

I got used to that cryptic make_function compiler error, as I tend to use events a lot.
As a rule of thumb, whenever registering to an event, the callback function or lambda should have 1 argument that is a non-const reference of the same type as the templated event’s type. (that sounds complicated !) An example might be better:

ofEvent<some_type> event; // some type can be whatever, `float`, `ofRectangle`, or any type.

void callback(some_type& t){ 
    // do something
}

The only exception are ofEvent<void> which don’t need arguments in their callback.

Alternatively, the callback function can return a bool which is used to either stop or continue the event propagation, thus, can be declared as:

bool callback(some_type& t){ 
    // do something
    return true; // if you want to stop propagation
    return false; // if you want to continue propagation
}

If the function returns true, means that the event was “used” and will stop propagating; any other listener for this event will not get its callback called.

There is another option, in which the callback function has 2 arguments and looks like:

void callback(const void* sender , some_type& t){ 
    // do something
}

It behaves in the same way as what explained before but you get a const void pointer to the object that triggered the event. As it is a void pointer you need to cast it to the correct type in order to do anything with it.

hope this helps

1 Like

This is great help! Thanks Roy!

I should have some time tonight to work on getting this working in my app and testing. I’ll post again when that’s done.

1 Like

Ok, yep, I finally got some time to re-implement it and test it some in my app, and it seems to be working fine so far!

It’s great to see this working!

Roy, your notes in the above post look really helpful for tracking callbacks from different objects. I didn’t find much documentation on how to use this, so I was homebrewing my own system for keeping track of which callbacks were which, and which were still out there, etc. I still need to do some of that, but being able to identify the sending object is useful.

I can post some sample code later.

So the basic pattern I’m using which is working is:

In class ofApp definition in ofApp.h:

        void urlResponse(ofHttpResponse & response);
	
        ofURLFileLoader UFL;
        ofHttpRequest request;

In ofApp.cpp:

void ofApp::setup(){
    // ...
    ofRegisterURLNotification(this);
}

void ofApp::urlResponse(ofHttpResponse & response) {
   // do whatever you want to respond to "response"
}

And to kick off a request, somewhere in class ofApp:

    request.url = "http://www.enworld.org/";
    request.body = "content";
    request.saveTo = false;
    request.contentType = "application/x-www-form-urlencoded";
    request.method = ofHttpRequest::POST;
    request.timeoutSeconds = 10;

    UFL.handleRequestAsync(request);

One thing I am not sure of yet, is whether I need to actually use multiple ofURLFileLoader and/or ofHttpRequest objects, if I’m blasting off many calls to handleRequestAsync() before they return, or not. So far for my purposes, it seems to work without doing that (i.e. re-using the same objects for each call with different values in them, even being called rapidly).