0

I tried to build a wrapper for a C module. The C module will do some CAN communication. To read something there is a read() function where a callback function pointer is passed with.

My idea was to make a Caller class where other classes (in example class A) can inherit from. I have now a problem in function "A::req()" with the comand "readObject()". To have no compiler errors I have to make a static_cast but then during excecution program will not work proberly. I already read that downcast in specialication can be dangerous. I guess my error is coming from that.

How could I solve my problem? Any ideas? Is there a design pattern which I should check?

Thanks.

class A : public Caller
{
    public:
        void req()
        {
            //readObject(&A::specializedCallback); // error from compiler
            readObject(static_cast<Caller::CbkPtr_t>(&A::specializedCallback)); // has error during excecution, because of downcast?
        }

        void specializedCallback(void *data);
}

class Caller
{
    public:
        typedef void (CanIfcCaller::*CbkPtr_t)(void *data);
        readObject(CbkPtr_t cbFcnt)
        {
            cbkFunction = cbFcnt;
            Wrapper::readObject(this):
        }

        void callbackReadObject(void *data)
        {
            (this->*cbkFunction)(data);
        }

    private:
        CbkPtr_t cbkFunction;
}

class Wrapper // to C function
{
    public:
        static void readObject(Caller* theCaller)
        {
            pCaller = theCaller;
            read(&Wrapper::callbackReadObject);
        }

        static void callbackReadObject(void *data)
        {
            pCaller->callbackReadObject(data);
        }


    private:
        Caller* pCaller;

}
Matt
  • 169
  • 1
  • 1
  • 7
  • 2
    Possible duplicate of http://stackoverflow.com/questions/26787464/is-this-c-callback-safe-with-c-objects – πάντα ῥεῖ Nov 07 '14 at 08:04
  • 1
    Did you forget the `this` in `Wrapper::readObject()`? – John Zwinck Nov 07 '14 at 08:05
  • @JohnZwinck You are right the this was lost during copying to stackoverflow. But it's not the real problem. – Matt Nov 07 '14 at 08:15
  • Are you also missing the parameter of `CbkPtr_t`? It seems to take no arguments, yet you use it as if it takes one. Also, what compiler error did you get when you didn't use `static_cast`? – John Zwinck Nov 07 '14 at 08:20
  • @JohnZwinck Added the missing parameter in typedef of `CbkPtr_t`. This is the error mesagge: _C:\...\A.cpp:169: Fehler: C2664: 'Caller::readObject' : cannot convert parameter 5 from 'void (__thiscall A::* )(void *,UINT32 *,UINT32 *,UINT8 *)' to 'Caller::CbkPtr_t' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast_ – Matt Nov 07 '14 at 09:00
  • 1
    Please provide code which compiles and doesn't "work properly". For me [everything works fine](http://coliru.stacked-crooked.com/a/10dd9bd36c9be1a4). – Anton Savin Nov 07 '14 at 09:06
  • @πάντα ῥεῖ It seems that I have problems which are discussed in your post. This is from this post: _The type you convert to the void* must be exactly the same type as the type you cast it back to in the callback. The classic error is to pass something like new Derived to the C function, and cast it back to Base* in the callback. The round trip Derived*→void*→Base* is undefined behavior. It will work some of the time, but at other times, it may crash, or cause any number of other problems._ – Matt Nov 07 '14 at 09:53
  • 1
    @Matt That's exactly why I had proposed it. You can't cast the `void*` directly to a derived class using `static_cast<>`, you'll need first cast void* to the base class pointer, and static cast this one to the derived class pointer. – πάντα ῥεῖ Nov 07 '14 at 09:56
  • @πάντα ῥεῖ So as I understand you I should make the casts in two steps. The `Caller::callbackReadObject()` I could make abstract. – Matt Nov 07 '14 at 10:18
  • @πάντα ῥεῖ Can you give me the example? I didn't understand. – Matt Nov 12 '14 at 12:13

0 Answers0