[英]function pointer with variable inputs
In C, I am trying to pass a single-variable function into an optimization routine ( optimization_routine
). 在C中,我试图将单变量函数传递给优化例程(
optimization_routine
)。 The optimization routine takes as input a pointer func1ptr
to a function of a single float
variable. 优化例程将指针
func1ptr
作为输入作为单个float
变量的函数。 However, I need to be able to pass multiple variables into this function. 但是,我需要能够将多个变量传递给此函数。 Thus, I am trying to construct a function pointer of one variable where all but the first inputs are "constants" into the function variable (sort of analogous to a partial derivative in calculus).
因此,我试图构造一个变量的函数指针,其中除了第一个输入之外的所有输入都是函数变量中的“常量”(类似于微积分中的偏导数)。 I think I can do this with function pointers, but I can't figure out a syntax that makes sense.
我想我可以用函数指针做到这一点,但我无法弄清楚有意义的语法。
That is, I have a function like this: 也就是说,我有这样的功能:
float function_all_inputs( float A, int B, float C, char D);
The optimization function requires a pointer like this: 优化函数需要一个像这样的指针:
typedef (*func1ptr)(float);
void optimization_function( func1ptr fp );
Thus, I want to construct a function of this form: 因此,我想构建一个这种形式的函数:
// create a function of A only at runtime using inputs B,C,D
func1ptr fp = ( & function_all_inputs(A,B,C,D))(A);
The function pointed to by fp
should have the signature: fp
指向的函数应该具有签名:
float function_one_input(float A);
Inputs B, C, and D are calculated elsewhere in the code, and thus are not known at compile-time; 输入B,C和D在代码的其他地方计算,因此在编译时是未知的; however, they are constant inside
optimization_function
. 但是,它们在
optimization_function
内是不变的。
I think I can do this in pure C using function pointers, however, I can't figure out the correct syntax. 我想我可以使用函数指针在纯C中执行此操作,但是,我无法弄清楚正确的语法。 None of the examples I found online cover this case.
我在网上找到的所有例子都不包括这种情况。 Any advice you can provide would be appreciated.
您可以提供的任何建议将不胜感激。
It sounds like you are asking how to create a closure to capture parameters in C, and you can take a look at some options in the linked question. 听起来你在问如何创建一个闭包来捕获C中的参数,你可以看看链接问题中的一些选项。
However, without custom extensions, I think you will need to use global variables to achieve the effect you are looking for. 但是,如果没有自定义扩展,我认为您需要使用全局变量来实现您正在寻找的效果。
// Pass this wrapper with the name "wrapper" into the function
// that requires a function pointer
void wrapper(float a) {
// Where last four arguments are global variables that are computed first.
function_all_inputs(a, b, c, d, e);
}
// No need to create an explicit function pointer.
// Passing the name of the function is sufficient.
optimization_function(wrapper);
You need to write a wrapper function, like 你需要编写一个包装函数,比如
int b;
float c;
char d;
int wrap(float a) {
return function_all_inputs(a, b, c, d);
}
Consider concurrency an re-entrancy though: 考虑并发性是一种重新入侵:
If multiple threads can use the wrapper, and need it to pass different data, make those globals thread-local: 如果多个线程可以使用包装器,并且需要它传递不同的数据,那么使这些全局线程本地化:
_Thread_local int b;
If you need full re-entrancy, things get complicated: 如果你需要完全重新入门,事情会变得复杂:
You need to (also) save the variables before using a nested invocation with different parameters. 在使用具有不同参数的嵌套调用之前,您还需要(也)保存变量。
Writing a second (and maybe third) version of the wrapper using different globals may be better. 使用不同的全局变量编写包装器的第二个(也许是第三个)版本可能会更好。
If you need more active at the same time, you can try a pool of those functions, though it gets unwieldy really fast. 如果你需要同时更多活动,你可以尝试这些功能的池,虽然它很快就变得笨拙。 Better change your optimization-function by adding a context-parameter, and pass those extra-parameters with that.
通过添加context-parameter更好地更改优化函数,并使用该参数传递这些额外参数。
For full freedom, you really need a way to write functions at runtime, at least enough to recover a context-pointer. 为了完全自由,你真的需要一种在运行时编写函数的方法,至少足以恢复上下文指针。 That's not possible in pure C though.
但这在纯C中是不可能的。
If sizeof(float) >= sizeof(void*)
on your platform, then you can "hack" it as follows: 如果您的平台上有
sizeof(float) >= sizeof(void*)
,那么您可以按如下方式“破解”它:
typedef struct
{
float a;
int b;
float c;
char d;
}
params;
int function_all_inputs(float a, int b, float c, char d)
{
...
}
int function_one_input(float f)
{
params* p;
memcpy((void*)&p, (void*)&f, sizeof(void*));
return function_all_inputs(p->a, p->b, p->c, p->d);
}
int optimize()
{
float f;
params v;
params* p = &v;
v.a = ...;
v.b = ...;
v.c = ...;
v.d = ...;
memcpy((void*)&f, (void*)&p, sizeof(void*));
return optimization_function(function_one_input, f);
}
You weren't very consistent in your question about the return-value type, so I used int
. 关于返回值类型的问题你不是很一致,所以我用了
int
。
This may be overkill, but libffi supports creating closures in the following way: 这可能有点过分,但libffi支持以下列方式创建闭包:
#include <stdio.h>
#include <ffi.h>
typedef struct BCD { int B; float C; char D; } BCD;
void function_one_input_binding
(ffi_cif* cif, int* result, void** args, BCD* bcd) {
*result = function_all_inputs(*(float*)args[0], bcd->B, bcd->C, bcd->D);
}
int main() {
ffi_cif cif;
ffi_type* args[1];
ffi_closure* closure;
int (*function_one_input)(float);
// Allocate a closure.
closure = ffi_closure_alloc(sizeof(ffi_closure), &function_one_input);
// Tell libffi the parameter and return types.
args[0] = &ffi_type_float;
ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_int, args);
// Bind closure data.
BCD bcd = { .B = 1, .C = 2.5, .D = 'x' };
ffi_prep_closure_loc(
closure, &cif, function_one_input_binding, &bcd, function_one_input);
// Call the function.
int result = function_one_input(42.5);
// Free the allocated closure.
ffi_closure_free(closure);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.