在 C 中将两个函数连接成一个函数

问题描述 投票:0回答:4

如何将两个不带参数且不返回任何内容的函数连接(或合并)到一个函数中?在 JavaScript 中我会这样做:

function f1() {
    console.log("f1 called");
}
function f2() {
    console.log("f2 called");
}
function function_concat(fa, fb) {
    var final = function() {
        fa();
        fb();
    };
    return final;
}
var merged = function_concat(fa, fb);
merged();

在C中,这就是我所拥有的:

#include <stdio.h>
#include <stdlib.h>

typedef void (*fptr)(void);
void f1() {
    printf("f1 called");
}
void f2() {
    printf("f2 called");
}

fptr function_concat(fa, fb) {
    // What to do here??
}
int main(int argc, const char **argv) {
    fptr merged = function_concat(f1, f2);
    fptr();
}

我知道我必须返回一个静态指针,但我无法在 C 中的函数中定义函数,这使得如果我已经在函数中则很难创建新函数。有人知道有办法做到这一点吗?

c function concatenation
4个回答
3
投票

您无法在 C 语言中在运行时定义函数,因此您唯一的选择是实现某种代理。您可以使用全局变量来引用函数指针,但要给出隐式答案,您无法在 C 中真正模拟这一点。

如果你需要改变

fa_
fb_
的接口,你需要再次调用
function_concat
,或者直接设置全局变量,但此时你就不需要代理函数了。

static fptr fa_, fb_;

void function_concat_proxy() {
    fa_();
    fb_();
}

fptr function_concat(fptr fa, fptr fb) {
    fa_ = fp;
    fb_ = fb;
    return function_concat_proxy;
}

1
投票

首先我要说的是,尝试模仿一种将函数视为一等公民的语言的行为,至少可以说是一个奇怪的请求。

或者,您可以为需要两个函数指针的类型创建一个新的

typedef
,然后调用它:

typedef void (*mptr)(fptr, fptr);

function_concat
看起来像:

void function_concat(fptr fa, fptr fb) {
    fa();
    fb();
}

main

int main(int argc, const char **argv) {
    mptr merged = function_concat;
    merged(f1, f2);
}

这类似于现在仅通过函数指针调用

function_concat(f1, f2)
。显然不完全是你要找的东西,但是,唉,我将其留在这里供参考。


0
投票

你不能在 c 中这样做。你可以做的就是在 function_concat 中调用你的 2 个函数:

void function_concat(fa, fb) {
    fa();
    fb();
}

0
投票

我很晚了,但对于每个需要它的人来说,你可以用 c 来做到这一点,但它是特定于平台的。基本上你分配可执行内存,修改二进制程序,将程序加载到可执行内存:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <stdint.h>
#include <errno.h>

typedef void void_ft(void);

void_ft* fcat(void_ft x, void_ft y) {
    char op[] = "\x48\xb8\x00\x00\x00\x00\x00\x00\x00\x00\xff\xd0\x48\xb8\x00\x00\x00\x00\x00\x00\x00\x00\xff\xd0\xc3"; // program binary with zeros as blank slates to insert function pointers
    void_ft *r = mmap(NULL, 25, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); // allocate executable memory for program
    if (r == MAP_FAILED) {
        fprintf(stderr, "Could not allocate executable memory: %s", strerror(errno));
        exit(-1);
    }
    *(uint64_t*)(&op[2]) = (uint64_t)x; // set zeros to function pointers
    *(uint64_t*)(&op[14]) = (uint64_t)y;
    memcpy(r, op, 25); // copy new program with custom functions to executable memory
    return r;
}

void x(void) {
    printf("Hello ");
}

void y(void) {
    printf("World!\n");
}


int main(int argc, char* argv[]) {
    void_ft *z = fcat(x, y);
    z();
    munmap(z, 25); //free executable memory
    return 0;
}

抱歉代码错误:3

© www.soinside.com 2019 - 2024. All rights reserved.