目标 C 中的函数指针

Function pointers in Objective C

本文关键字:函数 指针 目标      更新时间:2023-10-16

我在调试时遇到了以下代码。我能够正确获得结果,但我不理解此处定义的函数指针。

这里pNewMsgeFunc是在结构stRsStruct中创建的函数指针tNewMsg的别名。

RsMsg.h

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

消息.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};                                  

它说在结构中pNewMsgFunc将指向NewMsg()函数。

但是如果不使用地址初始化tNewMsg,我就无法理解它是如何可能的

NewMsg() 函数。但是这段代码运行良好。没有其他构造函数用于

使用函数 NewMsg() 的地址初始化函数指针。

事件.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
}

在这里,通过调用函数指针,我调用了静态NewMsg()函数。

但是这个函数是如何被调用的,因为pNewMsgFunc()没有分配NewMsg的地址。

我需要通过 pNewMsgFunc() 调用 NewMsg() 函数。上面的代码有什么要做任何更改吗?

编辑:

如何在目标 C 中实现相同的代码。此函数指针调用函数 其返回类型为类。所以虽然函数指针可以用 C 实现为它调用返回类型为类的函数无法在目标 C 中实现作为 C 函数。

这里 pNewMsgeFunc 是函数指针 tNewMsg 的别名,它是在结构 stRsStruct 中创建

的。

不,不是。 tNewMsg是标识类型的名称。

typedef RsMsg* (*tNewMsg)(void);

。但pNewMessageFunc是这种类型的对象。

这样看。 在此代码中:

typedef unsigned int uint;
uint n = 42;

n不是uint的别名。 相反,nuint 类型的变量。

因此,pNewMessageFunc是一个全局变量(类型为指针到函数,它不需要参数和返回指针到RsMsg),你永远不会初始化。

tNewMsg    pNewMessageFunc

不创建别名,它声明类型为 tNewMsg 的存储位置。我怀疑您没有在此处正确输入代码,因为在头文件中声明存储位置通常会导致重复的存储位置(即链接器错误)。

这看起来像一个构造函数

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

它需要一个tNewMsg,并大概将其存储在类的实例数据中。因此,您的RsMsg::CreateMessage函数可能有权访问初始化的函数指针。

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.

只是一个猜测,无法从您发布的代码中真正分辨出来。

让我印象深刻的第一件事是 分配一个指向stRsStruct的指针,但在分配它指向的内存之前使用它。 这是未定义的行为,您可以预期任何事情都会发生。 可能是由于其他调用,它恰好击中了堆栈的一部分,其中另一个函数具有指向实际内存的类似指针,并且您只是击中了旧的东西。 为了使任何事情重复发生,切勿取消引用指针而不将其指向某个实际内存块。