我正在尝试创建一个函数,在一个地方初始化每个OpenCV窗口的所有鼠标处理程序。代码在主循环中工作,但不在我的函数内部(是的,我通过引用传递) 问题似乎源于传递一个指向字符串的指针 - 当它出来时,另一方面它不会成功解除引用(*)。是什么给了什么?
这是我所说的最简单的例子(它为两个相同的窗口设置鼠标处理程序 - 一个窗口工作,另一个窗口不工作):
// mouse problem.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <string.h>
#include <iostream> //for cout, cin
using namespace std;
using namespace cv;
void onMouse(int event, int x, int y, int flags, void* param){
string windowname = *((string*)param); //just recasting the void* we passed into the mousehandler to string
if(windowname.empty()){
cout << "ERROR.";
}else{
cout << "SUCCESS for window:" << windowname;
}
cout << " param: "<< param << " windowname: "<< windowname << "\n";
}
void initializer(const string& name){
namedWindow( name, CV_WINDOW_AUTOSIZE );
cout << " initializing mouse handler for " << name << " with string at address :" << &name << "\n";
setMouseCallback(name, onMouse, (void*)&name); //this line is exactly the same as the other setmousecallback line
}
int _tmain(int argc, _TCHAR* argv[]){
string name; Mat src; VideoCapture cap(0); cap >> src; // get a single frame from camera
//this works just fine
name = "frameA";
namedWindow( name, CV_WINDOW_AUTOSIZE );
cout << " initializing mouse handler for " << name << " with string at address :" << &name << "\n";
setMouseCallback(name, onMouse, (void*)&name);
//this fails even though it contains the same code and we pass by reference
initializer("frameB");
imshow("frameA",src); imshow("frameB",src); //display frame - mouseing over them triggers the OnMouse() event
while(true){ //loop forever
waitKey(30);
}
return 0;
}
我将鼠标悬停在每个窗口一次之后here is the result。
真正 KILLS 的是,正如您在图片中看到的那样,字符串的地址已成功识别!将它投射到字符串没有错误!但是当我取消引用它时,它说它是空的!
是的,我确实试图避免使用Void *。可悲的是,我无法避免无效。 OpenCV要求void 是任何mousehandler函数的最后一个参数:(
答案 0 :(得分:2)
这个问题与演员阵容无关。您保留一个指向临时string
对象的指针,并且在对象超出范围后尝试取消引用该指针。
以下内容:
initializer("frameB");
相当于:
initializer(std::string("frameB"));
换句话说,创建了一个临时函数,该函数接受并保留该临时函数的地址。由于临时消息在语句结束时消失,因此您将留下一个悬空指针。