0

I am using a c dll in a c++ class. One of the member functions should call the following function that generates an interrupt and calls a service routine:

signed short __stdcall SetIrqConditions
(
    signed short DevNum,
    unsigned short bEnable,
    unsigned int dwIrqMask,
    void (__stdcall * funcExternalIsr)
    (
        signed short DevNum,
        unsigned int dwIrqStatus
    )
);

I am trying to call another member function of the same class as the last parameter of this function.(funcExternalIsr) When I tried to do this, the compiler complained that the function is not static. So I defined the callee function as a static function, but when I do that I cannot access other members of the class.

class myClass
{
public:
   int counter;
   void func1();
   static void __stdcall func2(signed short DevNum, unsigned int Status);
};

void myClass::func1()
{
    ...
    Result = SetIrqConditions(DevNum, TRUE, Mask, func2); --> no error here once func2 is static
}

void myClass::func2(signed short DevNum, unsigned int Status)
{
    counter++; --> invalid use of member 'counter' in static member function
}

I tried many different ways and did some research but I can't seem to get this working, any pointers in the right direction would be appreciated.

neko
  • 13
  • 4
  • Unfortunately, because of the way this API is designed, this is not possible. It is not compatible with C++. C++ simply does not work this way. The only possible workaround is to use a static thread local variable to store the object pointer, and use a trampoline wrapper to fetch it out and invoke the class method. – Sam Varshavchik Aug 21 '20 at 11:56
  • your error from above has nothing to do with C DLL. you are incrementing non-static counter within static func2 – StPiere Aug 21 '20 at 11:56

1 Answers1

0

Passing C++ class member function as a paremeter to C function

There is no way to do this with a non-static function, because C doesn't have such thing as a pointer to member function. C has only pointers to functions, and those cannot point to non-static member functions.

What you can do instead is to write a separate free wrapper function (or a static member function) where you call that non-static member function. Example:

void wrapper_function(demo args)
{
    instance.member_function(args);
}

The remaining question is where to get the class instance to call within the wrapper. The options are in general:

  • Pass it as an argument to the wrapper. This is quite often an option with well designed C style callbacks that have a void* argument. That appears to not be the case here.
  • Use a variable with static storage. This is not ideal because global state is evil.
  • Create a local automatic variable within the wrapper. This is often not useful when the state of the instance needs to be accessed elsewhere.
eerorika
  • 232,697
  • 12
  • 197
  • 326
  • What did you expect from an interrupt request service routine? This must be part of an OS API for interrupt handling. And it is a very common approach to only provide 1 or 2 integer parameters for the service routine - provided by underlying HAL. Calling it 'bad design' needs really deep insight. Other than that, this would make a good answer. – Red.Wave Aug 21 '20 at 14:37