繁体   English   中英

我可以以某种方式在ANSI C中使用嵌套函数吗?

[英]Can I somehow use nested functions in ANSI C?

我有高级语言的背景,例如Java / Kotlin / Scala。 现在我需要创建一个C库,但是我很难在没有闭包的情况下工作。

在GCC中有一个很好的扩展,称为“嵌套函数”,(如果我正确理解的话)正是我需要的。 Apple“阻止”扩展看起来也很有趣。 但我需要一个可以与任何编译器一起使用的代码。

现有解决方案是否存在? 我见过一些允许生成C代码的项目: https//github.com/dbohdan/compilers-targeting-c 但我真的不需要另一种语言,只需要一个功能 - 闭包。 (我认为很难保持完全不同的语言,结果C代码将不会被优化)。

UPD一些解释,为什么我需要闭包。

假设我们有一些函数, connect(void (*on_failed_callback)()); 它以某种方式管理连接,当连接丢失时,它会调用回调。 它需要0个参数,但我想创建一些函数,它将带来一些带回调的数据。 如果我已经正确理解,最常用的解决方案是使用一些arg connect(void (*on_failed_callback)(void *callback_arg), void* arg);传递回调connect(void (*on_failed_callback)(void *callback_arg), void* arg); 但它导致了样板代码,可以通过嵌套函数修复。

所以下一个代码:

void connect(void (*on_failed_callback)(void* arg), void* arg) {
    ...
    on_failed_callback(arg);
}

void print_error(char* error) {
    printf(error);
}

void main() {
    char *msg = "Failed connection";
    ...
    connect(print_error, msg);
}

可以简化为下一个:

void connect(void (*on_failed_callback)()) {
    ...
    on_failed_callback();
}

void print_error(char* error) {
    printf(error);
}

void main() {
    char* msg = "Failed connection";
    ...
    void callback() {
       print_error(msg);
    }
    connect(callback);
}

我的意思是,我想要一些工具/应用程序,用闭包/嵌套函数分析我的代码并生成纯ANSI C代码。

对于特定的示例,您已经询问过使用C的方法实现类似于闭包的方法,因为它将函数指针打包,并且需要与函数一起使用的数据。

typedef struct {
    char sBuff[128];              // data for the function to use
    void (* func) (char* error);  // pointer to function to execute
} ErrorMsg;

void connect(ErrorMsg myMsg) {
    ...
    myMsg.func(myMsg.sBuff);  // call the function with the packaged data
}

// the function that we will be encapsulating with the data to be
// used.
void print_error(char* error) {
    printf(error);
}

void main() {
    ErrorMsg msg = {"Failed connection", print_error} ;
    …
    connect(msg);  // invoke our function package and its data.
}

如果在使用函数包时,您希望添加其他数据,您可以按照以下方式执行此操作。

typedef struct {
    char sBuff[128];              // packaged data for the function to use
    void (* func) (char* error, int iExtra);  // pointer to function to execute
} ErrorMsg;

void connect(ErrorMsg myMsg) {
    ...
    myMsg.func(myMsg.sBuff, errno);  // call the function with the packaged data and extra info
}

// the function that we will be encapsulating with the data to be
// used.
void print_error(char* error, int iExtra) {
    printf(error, iExtra);
}

void main() {
    ErrorMsg msg = {"Failed connection: errno %d", print_error} ;
    …
    connect(msg);  // invoke our function package and its data.
}

现有解决方案是否存在?

这取决于你的意思。 标准C不提供闭包,嵌套函数或lambda /块作为语言功能。 但是在其他语言中没有任何东西可以用C语言中没有的任何或所有这些语言做。 事实上,某些语言中确实有这些功能本身用C实现

特别是,您的第一个示例大致是通用回调的正常C语言。 回调函数接受指向包含所需数据的对象的指针,并且回调注册接口接受指向适当对象的指针以及指向该函数的指针。 触发回调时,会将已注册的数据指针传递给它。

顺便提一下,请注意,这是一个比单独使用闭包更通用的工具,因为回调将在其上运行的数据不需要在定义函数的范围内。 除此之外,这允许提供标准的,可重用的回调实现,其中与特定数据的关联仅在回调注册时进行。 如果多个回调可以同时与同一事件相关联,则它还允许对同一事件重用相同的回调,并使用不同的数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM