Передача функции, которая возвращает void, но имеет целочисленные аргументы, в другую функцию как сам ARGUMENT - PullRequest
4 голосов
/ 12 октября 2010

Я недавно начал работать над OpenCV , используя c ++ .У меня проблема со следующим кодом.

#include "cv.h"
#include "highgui.h"
int g_slider_position = 0;
CvCapture* g_capture = NULL;

void onTrackbarSlide(int pos) {
  cvSetCaptureProperty(
    g_capture,
    CV_CAP_PROP_POS_FRAMES,
    pos
  );
}

int main( int argc, char** argv ) {
  cvNamedWindow( "Example3", CV_WINDOW_AUTOSIZE );
  g_capture = cvCreateFileCapture( "Aawaarapan.avi" );
  int frames = (int) cvGetCaptureProperty(
    g_capture,
    CV_CAP_PROP_FRAME_COUNT
  );
  if( frames!= 0 ) {
    cvCreateTrackbar(
      "Position",
      "Example3",
      &g_slider_position,
      frames,
      onTrackbarSlide //need to be call as onTrackbarSlide(g_slider_position) but gives error:invalid use of void expression 
    );
  }

  IplImage* frame;
  while(1) {
    frame = cvQueryFrame( g_capture );
    if( !frame ) break;

    cvShowImage( "Example3", frame );
    cvCreateTrackbar(
      "Position",
      "Example3",
      &g_slider_position,
      frames,
      onTrackbarSlide
    );

    char c = cvWaitKey(33);
    if( c == 27 ) break;

    ++g_slider_position;
  }

  cvReleaseCapture( &g_capture );
  cvDestroyWindow( "Example3" );
  return(0);
}

здесь вызов функции cvCreateTrackbar принимает в качестве аргумента функцию

void onTrackbarSlide(int pos)

, нокогда я вызываю функцию, подобную этой cvCreateTrackbar («Position», «Example3», & g_slider_position, frames, onTrackbarSlide (g_slider_position)); `

она сообщает об ошибке error: invalid use of void expression

На самом делеМне нужно передать g_slider_position в функцию, чтобы положение ползунка было известно.

Мой друг сказал мне вызвать функцию как

cvCreateTrackbar(
  "Position",
  "Example3",
  &g_slider_position,
  frames,
  onTrackbarSlide
);

, это не сообщает об ошибке, ноон не делает то, что должен. позиция ползунка необходима.

Итак, мой вопрос - как мне вызвать cvCreateTracker с аргументом onTrackerSlide (с целочисленным аргументом).Надеюсь, я не запутался.

Спасибо!

Ответы [ 2 ]

3 голосов
/ 12 октября 2010

g_slider_position доступно для вашей функции - вы не можете ее передать. Вы должны использовать код, который у вас есть (от вашего друга), но переданный int является идентификатором трекбара.

Должно быть так:

void onTrackbarSlide(int id) {
  cvSetCaptureProperty(
    g_capture,
    CV_CAP_PROP_POS_FRAMES,
    g_slider_position
  );
}
1 голос
/ 29 октября 2010

Это проблема использования указателя на функцию C, которую, я полагаю, вы никогда не использовали.

В момент создания трекбара вы действительно должны использовать:

cvCreateTrackbar(
  "Position",
  "Example3",
  &g_slider_position,
  frames,
  onTrackbarSlide
);

Когда вы делаете этот вызов, вы сообщаете OpenCV две части информации:

  1. адрес g_slider_position
  2. адрес onTrackbarSlide

Теперь, когда эта трекбар перемещается, OpenCV будет:

  1. напрямую изменять g_slider_position (так что вам даже не нужно получать его как параметр функции, но в любом случае)
  2. позвоните onTrackbarSlide(g_slider_position), что он может сделать, потому что знает обе части информации

Если вы напишите код так, как пытались:

cvCreateTrackbar(
  "Position",
  "Example3",
  &g_slider_position,
  frames,
  onTrackbarSlide(g_slider_position)
);

Где вы написали onTrackbarSlide(g_slider_position), это превратилось в вызов функции onTrackbarSlide.Другими словами, пытаясь выяснить, какие значения вы хотите передать cvCreateTrackbar, он вызвал onTrackbarSlide и передал ему текущее значение g_slider_position, и надеялся, что onTrackbarSlide вернет указатель на функцию, потому что эточто для этого нужно.ОК, он никогда не заходил так далеко, потому что он мог сказать во время компиляции, что onTrackbarSlide вернул void, и что void не было void(*aCallbackFunction)(int) (именно так вы определяете тип "функция, которая принимает intничего не возвращает "), но я использую стиль повествования ...

Что касается аргумента id против position, я не могу говорить по опыту.В документах, которые я только что прочитал из willowgarage, говорится, что ваш обратный вызов получает позицию, а не идентификатор, что означает, что у вас нет возможности использовать один обратный вызов для различения ползунков.Я лично не хотел бы делать это в любом случае, потому что это означает, что у меня была бы одна функция с переключателем вместо нескольких функций.Несколько функций (с микроскопической точки зрения) будут более эффективными и определенно более читабельными.

С другой стороны, cvCreateTrackbar возвращает int, который может быть идентификатором этого трекбара.Не уверен, что ты должен делать с этим, хотя.Фактическое значение возвращаемого значения не было определено на странице документа, которую я только что прочитал.Учитывая, что это API C и ему не хватает типа bool, int может быть просто возвращением true / false ...

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