将返回void但具有整数参数的函数传递给另一个函数作为ARGUMENT本身

时间:2010-10-12 18:25:53

标签: c++ function callback opencv function-parameter

我最近开始使用 c ++ 开发 OpenCV 。我遇到以下代码的问题。

#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(       “位置”,       “示例3”       &安培; g_slider_position,       帧,       onTrackbarSlide(g_slider_position)     );`

报告错误 error: invalid use of void expression

实际上我需要将g_slider_position传递给函数,以便知道滑块的位置。

我的一位朋友告诉我把这个功能称为

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

这不会报告任何错误但它没有按预期执行。滑块的位置是必要的。

所以,我的问题是如何使用参数onTrackerSlide(带有整数参数)调用cvCreateTracker。我希望我不会混淆。

谢谢!

2 个答案:

答案 0 :(得分:3)

您的函数可以访问

g_slider_position - 您无法通过它。你应该使用你的代码(来自你的朋友),但传递的int是轨迹栏的id。

应该是这样的:

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

答案 1 :(得分:1)

这是C函数指针使用的问题,我假设你从未使用过它。

在创建轨迹栏时,您确实应该使用:

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

当您拨打该电话时,您正在告诉OpenCV两条信息:

  1. g_slider_position
  2. 的地址
  3. onTrackbarSlide
  4. 的地址

    现在,当移动该轨迹栏时,OpenCV将:

    1. 直接修改g_slider_position(所以你实际上甚至不需要将它作为函数参数接收,但无论如何)
    2. 调用onTrackbarSlide(g_slider_position),它可以做,因为它知道这两条信息
    3. 如果您按照尝试的方式编写代码:

      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 vs position论点,我无法从经验中说出来。我刚从willowgarage中读到的文档说明你的回调接收位置而不是id,这意味着你无法使用单个回调来区分滑块。不管怎样,我个人不想这样做,因为它意味着我有一个带开关而不是多个功能的功能。多个功能将(显微镜下)更高效,并且更具可读性。

      另一方面,cvCreateTrackbar确实返回一个int,它可能是该trackbar的id。不过,不知道你应该怎么做。返回值的实际含义未在我刚刚阅读的doc页面上定义。鉴于这是一个C API并且缺少bool类型,int可能只是一个真/假的返回...