The function pointer you pass to the 'MHD_start_daemon' call (for the access handler callback) needs to have the exact same signature that's expected by MHD. I suspect you understand that given your comment about understanding the cause - I'm just level setting.
I'm not sure why you have "MHD_Result*" as your return type from your access handler function call, but that looks like the culprit. It should just be "MHD_Result" (not a pointer). You don't show your code, so I'm not sure if something funky is going on trying to blend C and C++. So, to be really thorough...
I'm not claiming to be an expert and I think there are other ways to do this, but I find this methodology relatively easy to understand:
With C++, you can pass in a C-version of the function with your "Http" object as the first argument (see the "this" below the "connectionCallbackC" line in the following code). Then, use that class instance pointer to call back into your Http class to do the actual work.
I.e., in your "Http" class, you could have something like this:
--------------------------
void Http::start() {
....
myDaemon = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION | MHD_ALLOW_UPGRADE | MHD_ALLOW_SUSPEND_RESUME, // one thread per connection; also 2 flags needed to support websockets
webPort, // port to listen on
nullptr, // accept policy callback
nullptr, // extra arg to accept policy callback
&connectionCallbackC, // main 'connection' callback (i.e., the "access handler" callback)
this, // extra argument to the 'connection' callback
MHD_OPTION_NOTIFY_COMPLETED, // specifies that the next arg is the callback to call when the connection is done
&requestCompletedCallbackC, // the callback to call when the connection is done
this, // extra arg to the callback when the connection is done
MHD_OPTION_CONNECTION_LIMIT, // specifies that the next arg is the max number of simultaneous connections
(unsigned int)100, // the number of permitted simultaneous connections
MHD_OPTION_CONNECTION_TIMEOUT, // specifies that the next arg is how long any given connection can live
(unsigned int)60, // the number of seconds connections are allowed to live (0 would allow them to live indefinitely)
MHD_OPTION_END); // no more options in the arg list
...
}
--------------------------
Then, outside the class, put a regular old C function as your callback, and have it just call back into your Http class using the pointer you provided:
// This could be at the top of your .cpp file or in your .hpp/.h file or whatever. It's just a function declaration.
extern "C" MHD_Result connectionCallbackC(void* cls, struct MHD_Connection* connection, const char* url, const char* method,
const char* version, const char* upload_data, size_t* upload_data_size, void** con_cls);
// This is the "C" function that gets called as the "access handler". You can then just have it call back into your "Http" class to process the data.
// The "cls" value is the one you gave MHD after the function pointer in the 'MHD_start_daemon' call. I.e., "this" (specifically, it's a pointer to your Http class).
MHD_Result connectionCallbackC(void* cls, struct MHD_Connection* connection, const char* url, const char* method,
const char* version, const char* upload_data, size_t* upload_data_size, void** con_cls) {
return ((Http*)cls)->connectionCallback(connection, url, method, version, upload_data, upload_data_size, con_cls);
}
// For completeness, here's the callback in the Http C++ code that gets called by the above C function:
MHD_Result Http::connectionCallback(struct MHD_Connection* connection, const char* url, const char* method,
const char* version, const char* uploadData, size_t* uploadDataSize, void** connPtr) { ... do stuff ... }
Also noteworthy: MHD very recently changed the type of "MHD_Result" from an int to an enum. Some example code out on the internet might be out of date. You have to use the real "MHD_Result" (not an int) or it will fail to compile for similar "type mismatch" reasons. (I literally just had to update my code a couple days ago when I updated to the latest MHD version - I had been counting on it being an int to make something a bit easier programmatically. Not hard to work around, of course.)
Hope that helps.
Ken