我的类中有一个成员函数:
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_ptr
到 handler lambda by [=] 它也是段错误。
如何正确制作?
UPD: 在处理程序主体中调用。
我找到那个成员(member)cv::Mat image
在 handler
之后变为 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/