Simplest C++ Callback, from SumatraPDF

https://news.ycombinator.com/rss Hits: 15
Summary

SumatraPDF is a Windows GUI application for viewing PDF, ePub and comic books written in C++. A common need in GUI programs is a callback. E.g. when a button is clicked we need to call a function with some data identifying which button was clicked. Callback is therefore a combo of function and data and we need to call the function with data as an argument. In programming language lingo, code + data combo is called a closure. C++ has std::function<> and lambdas (i.e. closures). Lambdas convert to std::function<> and capture local variables. Lambdas can be used as callbacks so problems solved? Not for me. I’ve used std::function<> and I’ve used lambdas and what pushed me away from them were crash reports. The problem with lambdas is that they are implemented as compiler-generated functions. They get non-descriptive, auto-generated names. When I look at call stack of a crash I can’t map the auto-generated closure name to a function in my code. It makes it harder to read crash reports. Simplest solution that could possibly work You should know up front that my solution is worse than std::function<> in most ways. It’s not as nice to type as a lambda, it supports a small subset of std::function<> functionality. On the other hand it’s small, fast and I can understand it. One thing you need to know about me is that despite working on SumatraPDF C++ code base for 16 years, I don’t know 80% of C++. I get by thanks to sticking to a small subset that I do understand. I don’t claim I’ve invented this particular method. It seems obvious in retrospect but it did take me 16 years to arrive at it. Implementation of a simple callback in C++ A closure is code + data A closure is conceptually simple. It combines code (function) and data: using func0Ptr = void (*)(void*); struct Func0 { func0Ptr fn; void* data; void Call() { fn(data); } }; There are 2 big problems with this. First is annoying casting. You have to do: struct MyFuncData { }; void MyFunc(void* voidData) { MyFuncData* data ...

First seen: 2025-06-15 19:06

Last seen: 2025-06-16 10:09