我想从objective-c调用c函数并将objective-c函数作为回调传递
问题是这个函数有一个回调作为参数,所以我必须将objective-c函数作为回调函数传递给c函数
这是c函数的标题
struct mg_context *mg_start(const struct mg_callbacks *callbacks,
void *user_data,
const char **configuration_options);
这是我试图称呼它的地方
- (void)serverstarted
{
NSLog(@"server started");
}
- (IBAction)startserver:(id)sender {
NSLog(@"server should start");
const char *options[] =
{
"document_root", "www",
"listening_ports", "8080",
NULL
};
mg_start(serverstarted(), NULL, options);
}
我已经尝试了几种方法来搜索网页,只是想知道怎么做但没有运气
这是我在代码中包含的库
答案 0 :(得分:5)
您的主要问题是mg_start()
的第一个参数,在声明中描述为const struct mg_callbacks *callbacks
。您正在尝试传递指向函数的指针。 (实际上你试图将调用的结果传递给该函数,这更远离标记。)这不是它所说的:它表示指向 struct 的指针(特别是,mg_callbacks
结构。)
https://github.com/valenok/mongoose/blob/master/examples/hello.c处的示例代码向您展示了如何配置此结构。您必须创建结构并将指针放入其中的回调函数。然后传递该结构的地址。
您的代码的其他问题:您的回调函数本身都是错误的:
- (void)serverstarted
{
NSLog(@"server started");
}
这里需要的是一个声明如下的C函数:int begin_request_handler(struct mg_connection *conn)
,即它将参数作为指向mg_connection
结构的指针。你的serverstarted
不仅不接受该参数,甚至不是C函数!这是一种Objective-C方法,一种完全不同的动物。您在标题和问题中使用“Objective-C函数”一词具有误导性; C有函数,Objective-C有方法。没有Objective-C将用于您将在此处编写的代码中。
我建议你在这里做的是首先复制hello.c
示例 slavishly 。然后慢慢地逐步修改事物的内容/名称,以将其演变为您自己的代码。当然,学习C也会有所帮助,但你可以通过仔细复制来获得。
答案 1 :(得分:3)
正如亚特已经说过,你不能将Objective-C方法作为C函数的回调传递 是期待。 Objective-C方法是特殊功能,特别是接收器(" self") 隐式地作为函数的第一个参数传递。
因此,要使用Objective-C方法作为请求处理程序,您需要一个(中间)C函数作为处理程序,并且必须使用self
参数将user_data
传递给该函数。然后C函数可以调用Objective-C方法:
// This is the Objective-C request handler method:
- (int)beginRequest:(struct mg_connection *)conn
{
// Your request handler ...
return 1;
}
// This is the intermediate C function:
static int begin_request_handler(struct mg_connection *conn) {
const struct mg_request_info *request_info = mg_get_request_info(conn);
// Cast the "user_data" back to an instance pointer of your class:
YourClass *mySelf = (__bridge YourClass *)request_info->user_data;
// Call instance method:
return [mySelf beginRequest:conn];
}
- (IBAction)startserver:(id)sender
{
struct mg_callbacks callbacks;
memset(&callbacks, 0, sizeof(callbacks));
callbacks.begin_request = begin_request_handler;
const char *options[] =
{
"document_root", "www",
"listening_ports", "8080",
NULL
};
// Pass "self" as "user_data" argument:
mg_start(&callbacks, (__bridge void *)self, options);
}
说明:
(__bridge ...)
管型。YourClass *mySelf
调用请求处理程序时无效。