3

I came across the following code while debugging. I was able to get the result correctly but I didn't not understand the function pointers defined in here.

Here pNewMsgeFunc is the alias name of the function pointer tNewMsg which is created inside the structure stRsStruct.

RsMsg.h

typedef RsMsg* (*tNewMsg)(void);
tNewMsg    pNewMsgFunc;
typedef struct
{
    int         nMsgId;       
    NSString*     sAsciiName;       
    tNewMsg    pNewMsgFunc; // calls new for the particular message
} stRsStruct;

RsMsg.cpp

RsMsg(int uMessageId,tNewMsg pNewMsg,const char* szAsciiName,void* pData,
      size_t uDataSize)
{
 //intialisations
}

RsMsgDerived.h

#define DECLARE_NEWMSG(CssName,CssID)                   \
    static CssName* FromMsg(RsMsg* pMsg)                \
    {                                                   \
        return dynamic_cast<CssName*>(pMsg);            \
    }                                                   \
    static RsMsg* NewMsg()                              \
    {                                                   \
        return new CssName;                             \
    }                                                   \
    enum {ID = CssID};                                  \

Its said that in the structure pNewMsgFunc will point to the NewMsg() function.

But I could not get it how its possible without intialising tNewMsg with the address of

the NewMsg() function.But this code is running fine.There is no other constructors used to

intialise the function pointer with the address of the function NewMsg().

Event.cpp

#import "RsMsg.h"
#import "RsMsgDerived.h"

RsMsg* RsMsg::CreateMessage(REMOTE_MESSAGE_ID nMessageNumber)
{
    RsMsg*       pMsg = NULL;
    stRsStruct*  pMsgStruct;

    pMsg = pMsgStruct->pNewMsgFunc();    //Invoking the function pointer
}

Here by invoking the function pointer I'm calling the static NewMsg() function.

But how this function gets called as pNewMsgFunc() is not assigned the address of NewMsg.

I need to call the NewMsg() function through pNewMsgFunc(). Is there any change to be made in the above code?

EDITED:

How to implement the same code in Objective C. This function pointer calls a function whose return type is a class.So though the function pointers can be implemented in C as its calling a function whose return type is a class cannot be implemented in Objective C as c function.

4
  • Most likely objective-c module files. Commented May 13, 2011 at 14:10
  • Could you clean up some things? You don't tell us what platform (Objective-C++?), and that may be significant in telling why things appear to behave. The code samples you list look odd: where do you use DECLARE_NEWMSG? Also, the title means almost nothing. Commented May 13, 2011 at 14:18
  • RsMsg::CreateMessage as you wrote it will almost certainly segfault. The pointer pMsgStruct is not initialized, so it could be pointing anywhere in memory. Then pMsgStruct->pNewMsgFunc() will load whatever random address is at that memory location and try to start executing code there. You should post more of the real code so that people can see what is happening. Commented May 13, 2011 at 14:20
  • Explain the hungarian notation for stRsStruct. Commented May 13, 2011 at 17:28

4 Answers 4

3

Here pNewMsgeFunc is the alias name of the function pointer tNewMsg which is created inside the structure stRsStruct

No, it's not. tNewMsg is a name that identifies a type.

typedef RsMsg* (*tNewMsg)(void);

...but pNewMessageFunc is an object of that type.

Look at it this way. In this code:

typedef unsigned int uint;
uint n = 42;

n is not an alias of uint. Rather, n is a variable of type uint.

So, pNewMessageFunc is a global variable (of type pointer-to-function-which-takes-no-parameters-and-returns-pointer-to-RsMsg) which you never initialize.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for explainng me clearly.I have edited the post please see it.
1

The line

tNewMsg    pNewMessageFunc

Does not create an alias, it declares a storage location of type tNewMsg. I suspect you've not entered your code correctly here as declaring a storage location in a header file generally results in duplicate storage locations (i.e. linker error).

This looks like a constructor function

RsMsg(int uMessageId,tNewMsg pNewMsg,const char* szAsciiName,void* pData,size_t uDataSize)
{
    //intialisations
}

Which takes a tNewMsg and presumably stores it in the class' instance data. So your RsMsg::CreateMessage function probably has access to the initialized function pointer.

Comments

0
RsMsg(int uMessageId,tNewMsg pNewMsg //this the function pointer as an arg to your initialization function, so I'm guessing the address of the correct function is passed here.

Only a guess, can't really tell from your posted code.

Comments

0

The first thing that strikes me is that you allocate a pointer to a stRsStruct, but use it before assigning the memory it points to. This is undefined behavior, and you can expect anything to happen. It may be that, due to other calls, it just happens to hit a piece of the stack where another function had a similar pointer that did point to actual memory, and that you're just hitting something old. In order to have anything happen repeatably, you should never dereference a pointer without pointing it to some actual memory block.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.