Есть некая либа RtAudio:
https://www.music.mcgill.ca/~gary/rtaudio/index.html
Ей требуется callback-функция:
https://www.music.mcgill.ca/~gary/rtaudio/RtAudio_8h.html#a112c7b7e25a974977f6fc094cef1a31f
Не могу раздуплить, как без лишних приседаний передать ей в качестве таковой "обычный" нестатический метод класса. Это вообще возможно?
Здравствуйте, XOOIOOX, Вы писали:
XOO>Есть некая либа RtAudio: https://www.music.mcgill.ca/~gary/rtaudio/index.html
XOO>Ей требуется callback-функция: https://www.music.mcgill.ca/~gary/rtaudio/RtAudio_8h.html#a112c7b7e25a974977f6fc094cef1a31f
XOO>Не могу раздуплить, как без лишних приседаний передать ей в качестве таковой "обычный" нестатический метод класса. Это вообще возможно?
Надо передаввать еще указатель на объект
Здравствуйте, XOOIOOX, Вы писали:
XOO>Не могу раздуплить, как без лишних приседаний передать ей в качестве таковой "обычный" нестатический метод класса. Это вообще возможно?
class MyFancyClientClass
{
public:
int RegularNonstaticMemberMethod(/*callback args without userData*/);
}
static int instanceDispatcher (/*callback args without userData*/, void *userData)
{
MyFancyClientClass * target = static_cast<MyFancyClientClass*>(userData);
return target->RegularNonstaticMemberMethod(/*callback args*/);
}
...
...
MyFancyClientClass foo;
...
RtAudio().OpenStream(....., instanceDispatcher, &foo,...)
ps/
вот с ErrorCallback-ом все печально, да.
Здравствуйте, XOOIOOX, Вы писали:
XOO>Есть некая либа RtAudio: https://www.music.mcgill.ca/~gary/rtaudio/index.html
XOO>Ей требуется callback-функция: https://www.music.mcgill.ca/~gary/rtaudio/RtAudio_8h.html#a112c7b7e25a974977f6fc094cef1a31f
XOO>Не могу раздуплить, как без лишних приседаний передать ей в качестве таковой "обычный" нестатический метод класса. Это вообще возможно?
| Если шашечки не важны и нужно что бы просто ехало, то можно так |
| // example.cpp
#include <stdio.h>
#include <string>
struct RtAudioError { typedef int Type; };
typedef void(* RtAudioErrorCallback)(RtAudioError::Type type, const std::string &errorText);
// Thunk.h
struct Thunk {
enum { max=8 }; // достаточное число. выбирается под задачу
struct Callback {
typedef void (*cb_fn)(void* ctx,RtAudioError::Type type, const std::string &errorText);
cb_fn cb; void *ctx;
Callback(cb_fn cb=0,void *ctx=0) : cb(cb),ctx(ctx) {}
};
static int set(int i,Callback cb);
static RtAudioErrorCallback get(int i);
};
// Thunk.cpp
static Thunk::Callback thunk[Thunk::max];
int Thunk::set(int i,Callback cb) {
if (i>=0 && i<max) { thunk[i]=cb; return 0; }
return 1;
}
#define THUNK(n) \
case n: { struct L { \
static void fn(RtAudioError::Type type, const std::string &errorText) { \
thunk[n].cb(thunk[n].ctx,type,errorText); \
} \
}; return L::fn; }
RtAudioErrorCallback Thunk::get(int i) { switch(i) {
THUNK(0)
THUNK(1)
THUNK(2)
THUNK(3)
THUNK(4)
THUNK(5)
THUNK(6)
THUNK(7)
// столько сколько нужно
} return 0; }
// usage.cpp
struct A {
void fn(RtAudioError::Type type, const std::string &errorText) { printf("A::fn\n"); }
static void _fn(void *ctx,RtAudioError::Type type, const std::string &errorText) { ((A*)ctx)->fn(type,errorText); }
};
struct B {
void fn(RtAudioError::Type type, const std::string &errorText) { printf("B::fn\n"); }
static void _fn(void *ctx,RtAudioError::Type type, const std::string &errorText) { ((B*)ctx)->fn(type,errorText); }
};
void call(RtAudioErrorCallback cb) {
std::string msg;
cb(0,msg);
}
int main(int argc,char** argv) {
A a[1]; B b[1];
Thunk::set(0,Thunk::Callback(A::_fn,a));
Thunk::set(1,Thunk::Callback(B::_fn,b));
call(Thunk::get(0));
call(Thunk::get(1));
return 0;
}
|
| |
Здравствуйте, XOOIOOX, Вы писали:
XOO>Есть некая либа RtAudio: https://www.music.mcgill.ca/~gary/rtaudio/index.html
XOO>Ей требуется callback-функция: https://www.music.mcgill.ca/~gary/rtaudio/RtAudio_8h.html#a112c7b7e25a974977f6fc094cef1a31f
XOO>Не могу раздуплить, как без лишних приседаний передать ей в качестве таковой "обычный" нестатический метод класса. Это вообще возможно?
Ну так там есть параметр
typedef int(* RtAudioCallback)(void *outputBuffer, void *inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status, void *userData)
При установке колбэка там наверняка передается *userData, которая потом в колбэк передается.
Вот туда и передавай указатель на this, а в качестве колбэка используй статическую функцию класса. В этой функции кастишь void к указателю на свой класс, и вызываешь уже нестатический метод. Этот прием стар, как само программирование.