Objective C 中将函数地址传递给函数指针

发布于 2024-11-09 08:22:15 字数 1378 浏览 0 评论 0原文

我需要将函数的地址传递给函数指针。下面是我的代码 试图完成它。我确信我在某个地方犯了错误,所以我得到了 运行时异常。如何将函数的地址传递给函数指针。我知道吗 这段代码中缺少一些东西。

RS232Msg.h

typedef RS232Msg* (*tpNewMsg)(void);
typedef struct
{
    int         nMessageId;         
    NSString*   szAsciiName;        
    tpNewMsg    pNewMessageFunc;   
} stRs232Struct;   
@interface RS232Msg : NSObject
{
}
@end

RS232Msg.m

@implementation RS232Msg
-(id)initWithRS232Msg:(int)uMessageId withNewMsg:(tpNewMsg)pNewMsg withAsciiName:(const char*)szAsciiName withData:(void*)pData withSize:(size_t)uDataSize
{
 //stmts;
}
@end

RS232Derived.h

@interface RS232MsgRequestSession : RS232Msg{
}

+(RS232Msg*)NewMsg;  

RS232Derived.m

@implementation RS232MsgRequestSession
+(id)FromMsg:(RS232Msg*)pMsg           
{                                                       
    pMsg = [RS232MsgRequestSession alloc];  
    return pMsg;
}             
-(id)init
{   
    if (self = [super initWithRS232Msg:[RS232MsgRequestSession getID] withNewMsg:[RS232MsgRequestSession NewMsg] withAsciiName:NULL withData:&st withSize:sizeof(st)]) {

    }
    return self;
}
@end

当我尝试将函数的地址传递

withNewMsg:
[RS232MsgRequestSession NewMsg]

给 initWithRS232Msg 中的函数指针 pNewMsg() 时,发生运行时异常 方法。

I need to pass a address of the function to a function pointer.Below is the code what i'm
trying to accomplish it.I'm sure that i'm mistaking somewhere so that i'm getting a
runtime exception.How to pass the address of a function to a function pointer.Am i
missing something in this code.

RS232Msg.h

typedef RS232Msg* (*tpNewMsg)(void);
typedef struct
{
    int         nMessageId;         
    NSString*   szAsciiName;        
    tpNewMsg    pNewMessageFunc;   
} stRs232Struct;   
@interface RS232Msg : NSObject
{
}
@end

RS232Msg.m

@implementation RS232Msg
-(id)initWithRS232Msg:(int)uMessageId withNewMsg:(tpNewMsg)pNewMsg withAsciiName:(const char*)szAsciiName withData:(void*)pData withSize:(size_t)uDataSize
{
 //stmts;
}
@end

RS232Derived.h

@interface RS232MsgRequestSession : RS232Msg{
}

+(RS232Msg*)NewMsg;  

RS232Derived.m

@implementation RS232MsgRequestSession
+(id)FromMsg:(RS232Msg*)pMsg           
{                                                       
    pMsg = [RS232MsgRequestSession alloc];  
    return pMsg;
}             
-(id)init
{   
    if (self = [super initWithRS232Msg:[RS232MsgRequestSession getID] withNewMsg:[RS232MsgRequestSession NewMsg] withAsciiName:NULL withData:&st withSize:sizeof(st)]) {

    }
    return self;
}
@end

A run time exception happens when i tried to pass the address of the function

withNewMsg:
[RS232MsgRequestSession NewMsg]

to the function pointer pNewMsg() in the initWithRS232Msg
method.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

神也荒唐 2024-11-16 08:22:15

[RS232MsgRequestSession NewMsg] 无法获取该方法的地址。计算表达式并将结果对象作为参数传递。虽然有一种方法可以直接访问方法的实现(请阅读 this< /a> 了解详细信息),可能有一种更简单的方法来实现您想要的。

基于选择器的方法

你可以考虑做这样的事情,而不是现在正在做的事情,

- (id) initWithTarget:(id)aTarget action:(SEL)aSelector ... {
    // save these two for later reference.
}

然后,

if ( [target respondsToSelector:theSelector] ) {
    result = [target performSelector:theSelector];
}

这样你就可以实现你想要的。

基于块的方法

说实话,事实证明,块是 Objective-C 的最佳补充。

将 typedef 更改为 typedef RS232Msg* (^tpNewMsg)(void);

现在 init 方法将变为,

-(id)init
{   
    self = [super initWithR232Msg:[RS232MsgRequestSession getID]
                       withNewMsg:^{
                           return [RS232MsgRequestSession NewMsg];
                       }
                    withAsciiName:NULL
                         withData:&st
                         withSize:sizeof(st)]
    if ( self ) {
        // do stuff
    }
    return self;
}
@end

[RS232MsgRequestSession NewMsg] doesn't get you the address of the method. The expression is evaluated and the result object is passed as the argument. While there is a way to access the implementation of a method directly (read this for details), there might be an easier way to achieve what you want.

Selector based approach

Instead of what you're doing right now, you can consider doing something like this,

- (id) initWithTarget:(id)aTarget action:(SEL)aSelector ... {
    // save these two for later reference.
}

and later,

if ( [target respondsToSelector:theSelector] ) {
    result = [target performSelector:theSelector];
}

This way you can achieve what you want.

Blocks based approach

Truth be told, Blocks are turning out to be the best addition to Objective-C.

Change the typedef to typedef RS232Msg* (^tpNewMsg)(void);

Now the init method would become,

-(id)init
{   
    self = [super initWithR232Msg:[RS232MsgRequestSession getID]
                       withNewMsg:^{
                           return [RS232MsgRequestSession NewMsg];
                       }
                    withAsciiName:NULL
                         withData:&st
                         withSize:sizeof(st)]
    if ( self ) {
        // do stuff
    }
    return self;
}
@end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文