0

I have a 3rd party library and I have to assign function pointers like this:

FunctionsStruct functionsStruct;

functionsStruct.firstFunctionPointer = myFirstFunction;
functionsStruct.secondFunctionPointer = mySecondFunction;
functionsStruct.thirdFunctionPointer = ...;

In myFirstFunction, mySecondFunction I use shared variables. It looks like this:

void myFirstFunction(int a, int b) {
    sharedVariable = 56 * a;
    ...
}

void mySecondFunction(int c) {
    sharedVariable = 21 + c;
    ...
}

Of course I can write a code in this way:

int sharedVariable;

void myFirstFunction(int a, int b) {
    sharedVariable = 56 * a;
    ...
}

void mySecondFunction(int c) {
    sharedVariable = 21 + c;
    ...
}

void setFunctionPointers() {
    FunctionsStruct functionsStruct;

    functionsStruct.firstFunctionPointer = myFirstFunction;
    functionsStruct.secondFunctionPointer = mySecondFunction;
    functionsStruct.thirdFunctionPointer = ...;
}

But I would like to avoid global / static variables + have classes.

So the best for me is something like this ( I know that I can't assign member function address to function pointers - I'm looking for something similar ) :

class A {
public:
    A(int sharedVar): sharedVariable(sharedVar) {};
    int sharedVariable {};
    void myFirstFunction(int a, int b);
    void mySecondFunction(int c);
}

class B {
private:
    A a;
public:
     B() {};
     void setFunctionPointers();  
}

void B::setFunctionPointers() {
    functionsStruct.firstFunctionPointer = &a::myFirstFunction;
    functionsStruct.secondFunctionPointer = &a::mySecondFunction;
    functionsStruct.thirdFunctionPointer = ...;
}

So what is the nicest solution?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Tommmmmm
  • 101
  • 8
  • you can have function pointers to static member functions, if that helps. – KungPhoo Mar 07 '23 at 06:45
  • @KungPhoo Thank you. Yes, this is the possible solution, but static variables are ugly like global variables ;) – Tommmmmm Mar 07 '23 at 06:50
  • You cannot avoid it since the signatures are bound to function pointers.. – Louis Go Mar 07 '23 at 07:13
  • You cannot avoid global variables using standard C++. There is a *non-standard, not universally portable* way to do it though. though. See https://www.gnu.org/software/libffcall/callback.html – n. m. could be an AI Mar 07 '23 at 07:26

2 Answers2

-1

You can use lambda with capturing, and it's dependent on your customization, but I assumed that you have a shared_ptr variable, so I just captured it by copying (increasing the ref-count).

As you said, you can use global (that is ugly in this case) or class, and in this manner, you can use lamda (that is the same as class declaring under skin).


struct FunctionsStruct {
  std::function<void(int, int)> firstFunctionPointer;
  std::function<void(int)> secondFunctionPointer;
};
void setFunctionPointers() {
  FunctionsStruct functionsStruct;
  auto sharedVariable = std::make_shared<int>();
  functionsStruct.firstFunctionPointer =
      [sharedVariable](int a, int b) -> void { *sharedVariable = 56 * a; };

  functionsStruct.secondFunctionPointer = [sharedVariable](int c) -> void {
    *sharedVariable = 21 + c;
  };
}

int main() { return 0; }

Another HM
  • 148
  • 10
-1

This is always a big frustration when using c++ with a c library. But it all depends on the situation.

Some C libraries allow you to store a void* data with your callback, which you could use for c style OOP, or use it to store your this pointer. This does not seem the case for your library.

So i am assuming that the callbacks don't have context, in which case you would use a singleton pattern. and have a function in your cpp file like:

void callback(...){
  MyClass::instance().callback(...);
}

It is a bit hard to give you more, since i don't know the function of the library.

David van rijn
  • 2,108
  • 9
  • 21