1

I am trying to link to an external library in my QT application. The external library has a header file with the following relevant code I'm trying to call:

 extern VGRABDEVICE_API bool V_AssignFrameSizeCallback(IGrabChannel* pChannel, void* pFunc);

In the demo C++ program provided, which has no problems compiling, the following relevant code is:

// in main.cpp    
void _stdcall MyFrameSizeCallback(T x) {
    do_stuff;
}

int main(int argc, char* argv[]) {
    IGrabChannel* pChannel0 = something;
    V_AssignFrameSizeCallback(pChannel0, MyFrameSizeCallback);
}

I am trying to incorporate this code into my QT application, but getting problems. In my mainwindow.cpp file:

void _stdcall MainWindow::MyFrameSizeCallback(T x) {
    do_stuff;
}

void MainWindow::someFunction() {
    IGrabChannel* pChannel0 = something;
    V_AssignFrameSizeCallback(pChannel0, &MainWindow::MyFrameSizeCallback);
}

The error I'm getting is:

error: C2664: 'bool V_AssignFrameSizeCallback(IGrabChannel *,void *)' :
cannot convert argument 2 from 'void (__cdecl MainWindow::* )(T)' to 'void *'
There is no context in which this conversion is possible

What do I need to do? Thanks.

4

1 回答 1

3

你有两个问题。首先,void*是数据指针,而不是函数指针。根据 C++ 标准,两者之间的转换预计不会起作用。一些平台提供了更强的保证……例如 WindowsGetProcAddress和 *nixdlsym将两者混合。

接下来,您&MainWindow::MyFrameSizeCallback的不是函数指针,而是指向成员函数的指针。调用它需要一个MainWindow对象,外部库对此一无所知。

您需要向库提供一个普通函数,而不是成员函数。如果你有办法获得MainWindow*对象指针,你可以调用它的成员函数来做真正的工作。有时库会提供一个“上下文”参数,该参数会传递给您的回调;这是放置对象指针的好地方。否则,您需要将您的存储MainWindow*在全局变量中。如果你只有一个很容易,而如果你有多个,你可能会去std::map<IGrabChannel*, MainWindow*>

代码:

MainWindow* MainWindow::the_window;

void MainWindow::MyFrameSizeCallback(T x)
{
    do_stuff;
}

void _stdcall MyFrameSizeCallbackShim(T x)
{
    MainWindow::the_window->MyFrameSizeCallback(x);
}

void MainWindow::someFunction()
{
    IGrabChannel* pChannel0 = something;
    the_window = this;
    V_AssignFrameSizeCallback(pChannel0, &MyFrameSizeCallbackShim);
}

如果参数x不是IGrabChannel,请相应地更改地图数据类型和插入逻辑。如果参数x不是某种唯一的可预测标识符,您可能仅限于对一个MainWindow实例进行回调。

于 2014-12-05T20:41:09.940 回答