79380925

Date: 2025-01-23 11:59:59
Score: 0.5
Natty:
Report link
std::function<void(double,unsigned char,unsigned char)> m_cbfunc;
//...
ExternalDLL_SetCallback((cbf_t)&m_cbfunc);

This actually compiles and runs, but the program terminates as soon as a callback is actually called.

Not surprising. You've passed to ExternalDLL_SetCallback an address that is not an address of an object of cbf_t type. Anything can happen with code like this, crash is likely to happen.

Because I need access to class members of MyClass inside the callback function, I want to have MyCallback become a class member.

No you don't. An argument to ExternalDLL_SetCallback must be of the declared type which is not a member function type. So what do you really need to do? Depends on your specific use case.

If all calls to the callback in your program are supposed to operate on a single MyClass object, you can store a global struct and simply use it:

struct CallbackContext {
  MyClass* classObject = nullptr;
} g_theContext;

void MyCallback(double a, unsigned char b, unsigned char* c)
{
  g_theContext.classObject->doClassStuff(a);
  //...
}

//...
// set callback
assert(g_theContext.classObject == nullptr); //once
g_theContext.classObject = this;
ExternalDLL_SetCallback(&MyCallback);

If the library supports multiple callbacks and you want to register a number of callbacks with different MyClass objects that, too, can be arranged:

struct CallbackContext {
  std::list<MyClass*> processors;
} g_theContext;


void MyCallback(double a, unsigned char b, unsigned char* c)
{
  for(MyClass* obj : processors){
    obj->doClassStuff(a);
    //...
  }
}

//...
// set callback
if(g_theContext.processors.empty()){
  ExternalDLL_SetCallback(&MyCallback); //once
}
g_theContext.processors.push_back(this);

Since the library itself is a global object, you're essentially enhancing it with MyClass* storage for this specific callback, but do it on your side of the code.

(Notice that this is a single-thread code; if callbacks can be registered and|or called from multiple threads, you'll need thread safety measures for the shared object g_theContext.)

Reasons:
  • Blacklisted phrase (0.5): I need
  • RegEx Blacklisted phrase (1): I want
  • Long answer (-1):
  • Has code block (-0.5):
  • Contains question mark (0.5):
Posted by: Abstraction