Существует непереносимое и довольно хакерское решение, которое имеет преимущество, по крайней мере, в том, чтобы быть поточно-ориентированным, а методы «батута» - нет.
Вы можете сгенерировать фактический машинный код функции на лету. Основная идея состоит в том, что у вас есть шаблон для вашей функции обратного вызова, который принимает указатель объекта и указатель на функцию-член и дает вам блок памяти кучи, который вы можете передать в библиотеку как функцию обратного вызова C, что при вызове развернется и вызовет функцию-член для этого объекта.
Это грязно, и вам придется предоставлять реализацию для любой новой платформы (каждый раз, когда меняется соглашение о вызовах), но она работает, поточно-ориентирована. (Конечно, вы также должны следить за DEP). Другое потоково-безопасное решение - прибегнуть к локальному хранилищу потоков (при условии, что вы знаете, что обратный вызов произойдет в том же потоке, что и сделанный вами вызов).
См. http://www.codeproject.com/KB/cpp/GenericThunks.aspx для примера того, как вы могли бы генерировать thunks.