2012-01-24 17 views
1

コールバック操作を行うサードパーティのライブラリを使用しています。 関数ポインタを取り込む関数を持っています。 問題は、クラスのメンバーである関数へのポインタを渡すことができないことです。コールバック用のメンバー関数ポインタ渡しの場合

私は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(); 

} 
+1

[メンバー関数へのポインタ](http://www.parashift.com/c++-faq-lite/pointers-to-members.html) –

+0

httpを読む://stackoverflow.com/questions/4296281/how-to-pass-member-function-to-a-function-pointer – Lol4t0

答えて

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 
    ... 
} 
0

私はQTを経験していないのですが、ほとんどのシグナリング/コールバックシステムは、標準の静的関数ポインタよりもメンバ関数のためのさまざまな方法があります。

例えば、SIGC++で、彼らは

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

を持っている私は、QTが似ていると思うだろう。

このようなメカニズムがない場合は、醜いながら効果的な、コールバックとして渡す静的関数を持つことができます。この静的関数は、次にメンバー関数を呼び出します。

0

非スタティックメンバ関数へのポインタは、C++標準で関数ポインタを解放することはできません。一般に、単純な「void *」より複雑な構造です。

DRIVE_HANDLEとクラスAのインスタンスの 'this'の間にグローバル(シリアル化されていれば、シリアライズされている場合)を1対1の関係に設定し、OnWriteCallbackでそのポインタを評価することをお勧めします/ OnReadCallbackが渡されたハンドル 'h'から渡される

関連する問題