如何将两个不带参数且不返回任何内容的函数连接(或合并)到一个函数中?在 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 语言中在运行时定义函数,因此您唯一的选择是实现某种代理。您可以使用全局变量来引用函数指针,但要给出隐式答案,您无法在 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;
}
首先我要说的是,尝试模仿一种将函数视为一等公民的语言的行为,至少可以说是一个奇怪的请求。
或者,您可以为需要两个函数指针的类型创建一个新的
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)
。显然不完全是你要找的东西,但是,唉,我将其留在这里供参考。
你不能在 c 中这样做。你可以做的就是在 function_concat 中调用你的 2 个函数:
void function_concat(fa, fb) {
fa();
fb();
}
我很晚了,但对于每个需要它的人来说,你可以用 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