我使用用C编写的lib,允许我读写midi文件。虽然我发现另一个用C ++编写的lib对我有用,但我仍然在努力解决这个问题:我怎么能在对象/类中使用C lib。 lib有一个调用,它接受midi文件的路径,然后是一些为特定的midi-event-types调用的函数指针。所以它看起来像这样(摘要):
int main( int argc, char** args )
{
readMidi( args[ 1 ], onMidiEvent, onSysEvent, onError, ... );
}
我尝试使用指向收集播放音符的类实例的指针:
class MidiNoteList;
template < MidiNoteList* VMidi > onError( short errmsg, char* msg ) { ... }
...
int main( int argc, char** args )
{
MidiNoteList* m( new MidiNoteList( ) );
readMidi( args[ 1 ], onMidiEvent< m >, onSysEvent< m >, onError< m >, ... );
}
GCC说m不能用作常数表达式。我知道m必须在编译时保持不变,所以我确定为什么我不能这样做。但是我怎样才能解决这个问题&#34;在另一方面?
答案 0 :(得分:3)
通常这些库使用额外的void *
参数,该参数传递给接受函数指针的函数,并传递回所有回调函数。如果你有,你可以使用它来传递你的对象指针,将其转换为void并返回:
class MyObject;
void errCallback(void *m, short errcode, char *errmsg) {
static_cast<MyObject *>(m)->error(errcode, errmsg);
}
:
MyObject *m = new MyObject();
callLibrary(..., errCallback, m, ...);
如果库没有给你额外的参数,你就会遇到问题 - 在回调函数中获取额外数据的唯一方法是使用全局变量:
static MyObject *m;
void errCallback(short errcode, char *errmsg) {
m->error(errcode, errmsg);
}
:
m = new MyObject();
callLibrary(..., errCallback, ...);
这里的问题是你需要为你想要接收回调的每个不同对象声明一个新的回调函数(和全局变量)。如果动态创建许多此类对象,则管理起来变得难以管理。