成员函数指针传递回调用例

时间:2012-01-24 16:31:54

标签: c++ qt

我使用第三方库进行回调操作。 它有一个函数,它接收函数指针。 问题是我无法将指针传递给属于类成员的函数。

我正在使用Qt和C ++。第三方库函数似乎是一个C函数。 第三方提供的示例代码将所有代码放在main中。 这是不可取的,我需要在类中包装代码。

如何解决此回调问题?

A.H

#include "ThirdPartyLibrary.h"
class A
{
public:
    QFile* f;

    A(QString filename);
    ~A();

    bool mount();

    BOOL _stdcall OnWriteCallback
    (
        DRIVE_HANDLE h, 
        ULONGLONG WriteOffset, 
        ULONG WriteSize, 
        const void* WriteBuffer, 
        ULONG *BytesWritten
    );

    BOOL _stdcall OnReadCallback
    (
        DRIVE_HANDLE h, 
        ULONGLONG ReadOffset, 
        ULONG ReadSize, 
        void* ReadBuffer, 
        ULONG *BytesRead
    );
};

A.cpp

A::A(QString filename)
{
    f = new QFile(filename);
    f.open(QFile::ReadWrite);
}

~A::A(){
    f.close();
    delete f;
}

bool A::mount()
{
    //THIS IS THE PROBLEM, CreateVirtualDrive does not take MEMBER FUNCTION POINTERS 
    //properly, instead it wants normal function pointers.
    //CreateVirtualDrive is from an external 3rd-party 
    //library, and seems to be a C function.
    g_hDrive = CreateVirtualDrive(driveLetter,DISK_SIZE,
                                  &A::OnReadCallback,
                                  &A::OnWriteCallback);
}

BOOL _stdcall A::OnWriteCallback
(
    DRIVE_HANDLE h, 
    ULONGLONG WriteOffset, 
    ULONG WriteSize, 
    const void* WriteBuffer, 
    ULONG *BytesWritten
){
    //do some work with QFile f !!
    return true;
}

BOOL _stdcall A::OnReadCallback
(
    DRIVE_HANDLE h, 
    ULONGLONG ReadOffset, 
    ULONG ReadSize, 
    void* ReadBuffer, 
    ULONG *BytesRead
){
    //do some work with QFile f !!
    return true;
}

的main.cpp

#include "A.h"
int main ()
{
    A a;
    a.mount();

}

3 个答案:

答案 0 :(得分:2)

C++ FAQ中描述了一种解决方法:

 class Fred {
 public:
   void memberFn();
   static void staticMemberFn();  // A static member function can usually handle it
   ...
 };

 // Wrapper function uses a global to remember the object:
 Fred* object_which_will_handle_signal;

 void Fred_memberFn_wrapper()
 {
   object_which_will_handle_signal->memberFn();
 }

 int main()
 {
   /* signal(SIGINT, Fred::memberFn); */   // Can NOT do this
   signal(SIGINT, Fred_memberFn_wrapper);  // OK
   signal(SIGINT, Fred::staticMemberFn);   // OK usually; see below
   ...
 } 

答案 1 :(得分:0)

我对QT没有经验,但是大多数信令/回调系统对于成员函数有不同于标准静态函数指针的方法。

例如,在sigc ++中,他们有

signal.connect(sigc::mem_fun(this, &Class::function));

我认为QT是相似的。

如果没有这样的机制,你可以,丑陋但有效,有一个静态函数,你作为回调传递,然后调用你的成员函数。

答案 2 :(得分:0)

指向非静态成员函数的指针无法通过C ++标准转换为自由函数指针,因为通常它们的结构比普通的'void *'更复杂。

在你的情况下,最好建立全局(序列化,如果你有多线程)DRIVE_HANDLE和A类实例的'this'之间的一对一关联,并在OnWriteCallback /中评估该指针传入句柄'h'的OnReadCallback。