c++ - 如何成功地将功能对象(或 lambda)传递给轨迹栏回调的第二个参数(void*)?

标签 c++ multithreading opencv c++11

我的类中有一个成员函数:

void handler(int pos, cv::Mat &image)
{
    threshold(image, image, pos, 255, CV_THRESH_BINARY);
    cv::imshow("window", this->image); //<-- segfault
}

并且有一个createTrackbar的成员回调函数:

static void on_trackbar(int pos, void* ptr);

然后我在另一个成员函数中创建这个函数对象:

std::function<void(int)> bind_handler = std::bind(static_cast<void (my_class::*)(int, cv::Mat&)>(&my_class::handler), this, std::placeholders::_1, img_threshold);
slider = 0;
cv::namedWindow("Test Filter", 1);
cv::createTrackbar("threshold", "Test Filter", &slider, 255, on_trackbar, (void*)&bind_handler);

然后在 on_trackbar 中我捕捉到了 void* ptr:

std::function<void(int)>* cb = static_cast<std::function<void(int)>* >(ptr);
(*cb)(pos); //<-- segfault

编译成功。

但是当我触摸 slider 时它会出现段错误:(

我也试过this code with lambdas但它也有段错误。

如果我取 std::shared_ptr<cv::Mat> thrsh_ptrhandler lambda by [=] 它也是段错误。

如何正确制作?

UPD: 在处理程序主体中调用。 我找到那个成员(member)cv::Mat imagehandler 之后变为 0x0成员函数被调用 on_trackbar打回来。我在cv::createTrackbar之前检查了它的地址和里面handler body ;在这两种情况下,它都是相同的地址值。

最佳答案

如评论中所述,bind_handler是一个局部变量,在创建轨迹栏后立即消失。当库尝试调用回调时,它会进入您的 on_trackbar()函数,将指针传递给现已失效的 std::function<>对象,当您尝试取消引用它时会导致崩溃。那void* ptr参数指向不再存在的先前局部变量。

作为@n.m,你需要做什么。提到,是传递一个指向包含cv::Mat的对象的指针 .里面bind_handler() , 你投了 void*参数返回到您的对象类型,并从那里访问图像,调用您希望的任何成员函数。你的问题不够明确,我无法理解你的完整设计,但是是这样的:

class MyClass {
    cv::Mat img_threshold;

    void handler(int pos) {
        cv::threshold(img_threshold, img_threshold, pos, 255, CV_THRESH_BINARY);
        cv::imshow("window", img_threshold);
    }

public:
    static void on_trackbar(int pos, void* ptr) {
        MyClass* obj = reinterpret_cast<MyClass*>(ptr);
        obj->handler(pos);
    }

    void other_function() {
        slider = 0;
        cv::namedWindow("Test Filter", 1);
        cv::createTrackbar("threshold", "Test Filter", &slider, 255, on_trackbar, static_cast<void*>(this));
    }
};

关于c++ - 如何成功地将功能对象(或 lambda)传递给轨迹栏回调的第二个参数(void*)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51471316/

相关文章:

c++ - 分割 64 位值以适合 double 参数类型

c++ - CGAL::Surface_mesh_parameterization: 把顶点写到off按原来的顺序

c++ - opencv_contrib 编译错误 : class has no member

opencv - Opencv 的新 Haarcascade

macos - 如何使用 OpenCV 编写视频文件?

c++ - 采用 Enum 参数的工厂函数

c++ - 为什么 deques 默认用作堆栈的底层容器,而 vectors 可以做到这一点?

java - 多线程简单死锁错误逃避检测

java - Java 中的线程 : How to lock an object?

c# - 为什么这个 Parallel.ForEach 循环没有提高性能?