0

我的应用程序库需要调用一个优化例程:

 err = optim(int n, double *x, double *f, void *obj)

然后该例程将调用目标函数来请求目标函数值。

 void obj(int n, double *x, double *f)

optim() 是外部库的一部分。optim() 和 obj() 的签名是固定的。

该函数obj()需要访问单个对象“模型”中包含的数据。所有其他函数都传递指向模型对象的指针。因此,运行优化器的调用可能类似于:

 err = doOptimize(model)

doOptimize()将设置问题并致电optim()

 err= optim(model->n, model->x, model->f, model->obj)

问题是,除了、和之外,obj()函数还能访问对象中的变量吗?函数需要调用需要对象进行实际计算的其他函数:modelnxfobj()model

    updateParms(model);
    computeF(model);

我不确定在obj()没有实际句柄的情况下如何进行这些调用?以下可以工作吗?

    updateParms();
    computeF();      

谢谢,

4

2 回答 2

1

是的,没有。

当然,您的函数obj可以像访问任何其他内存一样访问模型,但我没有看到任何机制让它知道model.

您需要添加另一个参数obj来传递model指针。

在 C++ 中,您可能会通过obj创建Class Model. 然后编译器将添加一个名为this(它为所有成员函数执行此操作)的隐藏参数,该参数将包含指向对象实例“模型”的指针。如果你想在纯 C 中实现同样的效果,那么你必须传递你自己的this指针(但你可以随意调用它)。

所以,像这样:

... doOptimize (... model)
{
  ....
  optim (model->n, model->x, model->x, model)
  ....
}

... optim (int n, double *x, double *f, ... model)
{
  ....
  model->obj (n, x, f, model);
  ....
}

void obj (int n, double *x, double *f, ... model)
{
   /* use n, x, and f */
   /* use model->stuff */
}

当然,如果你总是使用相同的,n那么你只需要 pass 。xfmodel

顺便说一句,不要void *用于函数指针:这不是一个好主意。

于 2012-06-11T15:57:35.697 回答
0

由于您无法修改optim()obj()您将需要创建一个中间步骤来执行对您的obj()函数的真正调用。根据需要一次进行多少优化调用,这可能与保存模型指针的全局/静态变量一样简单,例如:

void obj(struct model *m, int n, double *x, double *f)
{
    /* Access to all information here */
}

static struct model *optim_model;

void obj_caller(int n, double *x, double *f)
{
    obj(optim_model, n, x, f);
}

int doOptimize(struct model *m)
{
    optim_model = m;
    return optim(m->n, m->x, m->f, obj_caller);
}

或者,如果您需要更高级或不喜欢拥有单个全局,并且可以使用 n 参数作为标识符,您可以使用它来突破以调用多个优化模型:

void obj(struct model *m, int n, double *x, double *f)
{
    /* Access to all information here */
}

#define MAX_MODELS (10)
static struct model *optim_models[MAX_MODELS] = {0};

void obj_caller(int n, double *x, double *f)
{
    for (int i = 0; i < MAX_MODELS; i++)
    {
        if (optim_models[i]->n == n)
        {
            obj(optim_models[i], n, x, f);
            break;
        }
    }
}

int doOptimize(struct model *m)
{
    return optim(m->n, m->x, m->f, obj_caller);
}

int main(void)
{
    struct model m1;
    struct model m2;

    m1.n = 1;
    optim_models[0] = &m1;

    m2.n = 2;
    optim_models[1] = &m1;

    int err = doOptimize(&m2);
}

我敢肯定,如果需要,您会找到一种更合适的方法来存储多个模型,例如具有真实标识符的链表。

于 2012-06-12T08:08:13.373 回答