Очень простой вопрос об аргументе с подписью void * data - PullRequest
3 голосов
/ 29 сентября 2011

Скорее всего, это очень простой вопрос - извините за это.

Я написал интерфейс на C ++, который работает на движке C. Одна из функций C-engine имеет следующую подпись:

static int f(double t, double *y, double *ydot, void *data)

Смысл *data - передавать пользовательские данные в ODE-решатель. Теперь в C я просто создаю struct, инициализирую его с моими данными и передаю. В C ++ я хочу создать класс, содержащий пользовательские данные, и передать его, как я ранее передал struct. Это может быть сделано, поскольку structs являются classes.

Однако, когда я пытаюсь это сделать, происходит следующее:

int.cpp:25: error: no matching function for call to ‘UserData::UserData()’
int.cpp:13: note: candidates are: UserData::UserData(double)
int.cpp:5: note:                 UserData::UserData(const UserData&)
int.cpp:28: error: ‘void*’ is not a pointer-to-object type
int.cpp:29: error: ‘void*’ is not a pointer-to-object type

Мои вопросы следующие:

  1. Что означает запись void *data?
  2. Почему жалуется, что у меня нет конструктора с соответствующей подписью?

Очевидно, я очень новичок, так что извините, если это очень очевидно, но я даже не знаю, какие термины использовать, чтобы погуглить проблему (в дополнение к поиску самой ошибки).

Спасибо!

Редактировать:

Прошу прощения за неопределенность предыдущего вопроса. Кроме того, я решил проблему, и это была очень глупая ошибка.

У меня был класс, содержащий параметры:

class Data{
// an interface to get parameters
};

и мне нужно было вызвать функцию C с подписью

static int f(double t, ...., void *user_data)

Я ошибочно сделал это:

static int f(double t, ...., void *user_data){
 Data *data = (Data*) data; /* this is the stupid mistake */
}

Когда я хотел это сделать (теперь это работает):

static int f(double t, ...., void *user_data){
 Data *data = (Data*) user_data; /* this is the correction  */
}

Спасибо всем - и я ценю указание правильного значения void *data.

1 Ответ

3 голосов
/ 29 сентября 2011
void *data 

означает указатель на любой адрес. Это нетипичный способ передачи данных произвольного типа. Это общий шаблон в C для реализации того, что будет сделано с функциональным объектом в C ++. Параметр данных, вероятно, на самом деле используется не вашим решателем ODE, а предоставленным вами обратным вызовом. Вы и обратный вызов должны знать, на что указывают данные, а решатель ODE - нет. Решатель просто передает адрес функции обратного вызова.

В качестве простого примера, предположим, что в библиотеке была функция поиска корня функции в одной переменной

  typedef double (*valuation_function) (double x, void * params);
  double find_root(valuation_function fn, double lower, double upper, void* params);

Функция params дает вам возможность написать параметризованную функцию. Предположим, вы хотите найти корень строки.

struct Line {
  double slope;
  double intercept;
  public:
     Line(double s, double i) : slope(s), intercept(i) {}
};

double a_line(double x, void *params) {
  Line* line = (Line *)params;
  return line->slope * x + line->intercept;
}

Затем вы можете вызвать функцию find_root для любой строки. Строка сорок пятая (1,0, 0,0); find_root (a_line, сорокFive);

Вы можете посмотреть в библиотеке gsl больше примеров .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...