【问题标题】:Why does casting a string pointer to a void pointer and back cause the string data to dissappear? (Opencv)为什么将字符串指针转换为 void 指针并返回会导致字符串数据消失? (OpenCV)
【发布时间】:2012-12-14 22:32:26
【问题描述】:

我正在尝试创建一个函数,在一个地方为每个 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*。可悲的是,我无法避免 void。 OpenCV 要求 void 作为任何鼠标处理函数的最后一个参数 :(

【问题讨论】:

    标签: string pointers opencv void


    【解决方案1】:

    问题与演员表无关。您保留了一个指向临时 string 对象的指针,并试图在对象超出范围后取消引用该指针。

    以下内容:

    initializer("frameB");
    

    相当于:

    initializer(std::string("frameB"));
    

    换句话说,创建了一个临时地址,该函数获取并保留该临时地址的地址。由于临时变量在语句结束时消失了,因此您只剩下一个悬空指针。

    【讨论】:

    • 那么我看到的 frameB 所指的地址是什么?
    • 你是对的。 :) 很简单。谢谢!那么我怎样才能在没有这个问题的情况下传入一个字符串呢?我不能,可以吗?我必须将每个字符串保存在自己的单独变量中吗?这种方式违背了将其包含在函数中的意义。 :(
    猜你喜欢
    • 2019-05-09
    • 2021-07-11
    • 2013-03-06
    • 1970-01-01
    • 2011-12-12
    • 2013-08-03
    • 2012-05-25
    • 2012-04-26
    • 2013-01-11
    相关资源
    最近更新 更多