Frage

Zunächst einmal muß ich zugeben, dass meine Programmierkenntnisse ziemlich begrenzt sind, und ich nahm eine (sehr klein) bestehende C über ++ OOP Projekt, bei dem ich versuche, in meine eigenen Sachen zu schieben. Leider ein Problem ich erlebe, die über das hinausgeht mein Wissen und ich hoffen, hier etwas Hilfe zu finden. Ich arbeite mit einem Dritten Bibliothek (die nicht geändert werden kann) für Bilder von einer Kamera greifen und werde einige Platzhalter Namen hier verwenden.

Die Dritte Bibliothek hat eine Funktion „ThirdPartyGrab“ eine kontinuierliche Live greifen zu beginnen und nimmt einen Zeiger auf eine Funktion, die jedes Mal, wenn ein neuer Rahmen Eingang angerufen werden. So in einem normalen C-Anwendung geht es wie folgt aus:

ThirdPartyGrab (HookFunction);

"HookFunction" muss als deklariert werden:

long _stdcall HookFunction (long, long, void*);

oder "BUF_HOOK_FUNCTION_PTR", die als

deklariert
typedef long (_stdcall *HOOK_FUNCTION_PTR) (long, long, void*);

Jetzt habe ich eine C ++ Anwendung und eine Klasse „MyFrameGrabber“, die alles einkapseln soll ich tun. Also habe ich in der Hook-Funktion als Privat Mitglied wie folgt aus:

long _stdcall HookFunction (long, long, void*);

Auch gibt es eine public void Funktion „StartGrab“ in meiner Klasse, die das Besorgen beginnen soll. Im Inneren Ich versuche zu nennen:

ThirdPartyGrab (..., HookFunction, ...);

, die (nicht überraschend) ausfällt. Er sagt, dass der Funktionsaufruf MyFrameGrabber :: HookFunction vermisst die Liste Argument und ich sollte versuchen, verwenden & MyFrameGrabber :: HookFunction einen Zeiger stattdessen zu erstellen. Jedoch vorbei „& MyFrameGrabber :: HookFunction“ führt stattdessen in einem anderen Fehler, dass dies nicht BUF_HOOK_FUNCTION_PTR umgewandelt werden.

Nach dem Lesen durch die C ++ FAQ Funktionszeiger ich glaube, ich das Problem verstehen, kann aber keine Lösung bilden. Ich habe versucht, die Hook-Funktion statisch zu machen, aber dies führt auch zu einem Konvertierungsfehler. Ich dachte auch außerhalb der Klasse der Hook-Funktion des Setzens, aber ich brauche Klassenfunktionen innerhalb der Hook-Funktion zu verwenden. Gibt es eine andere Art und Weise oder muss ich mein ganzes Konzept ändern?

EDIT 14.01.08: Getestet habe ich die Singleton Abhilfe, da ich nicht die Dritte Bibliothek ändern kann und der void-Zeiger ist nur für Daten, die innerhalb der Hook-Funktion verwendet wird. Leider hat es nicht aus dem Kasten heraus gearbeitet, wie ich gehofft .... Ich weiß nicht, ob die statische Funktion in einer separaten Klasse sein muss, so habe ich es in meiner „MyFrameGrabber“ Klasse:

static MyFrameGrabber& instance()
{
        static MyFrameGrabber _instance;
        return _instance;
}
long Hook(long, long, void*); // Implementation is in a separate cpp file

In meiner CPP-Datei Ich habe die call_hook Funktion:

long MFTYPE call_hook(long x, MIL_ID y, void MPTYPE *z)
{
    return MyFrameGrabber::instance().Hook(x,y,z);
}
void
MyFrameGrabber::grab ()
{
    ThirdPartyGrab(..., call_hook, ...);
}

Aber das gibt mir einen Fehler in static MatroxFrameGrabber _instance;, die kein passenden Standard-Konstruktor gefunden wird. Das ist richtig, weil mein MyFrameGrabber Konstruktor wie folgt aussieht:

MyFrameGrabber (void* x,
                const std::string &y, int z,
                std::string &zz);

Ich habe versucht, in einer leeren Konstruktor MyFrameGrabber(); zu setzen, aber dies führt zu einem Linkerfehler. Soll ich passieren leer Parameter an den Konstruktor MyFrameGrabber im Singleton? Oder muss ich eine separate Haken Klasse haben, und wenn ja, wie könnte ich MyFrameGrabber Funktionen zugreifen? Danke im Voraus.

ZWEITE EDIT 15.01.08: Ich bewarb mich um die Änderungen und es kompiliert und Links jetzt. Leider kann ich das noch nicht zur Laufzeit testen, da es sich um eine DLL ist und ich habe keine Debug Caller Exe noch und es gibt andere Probleme bei der Initialisierung usw. werde ich den Posten als Antwort markieren, weil ich sicher bin, dies ist der richtige Weg, dies zu tun.

War es hilfreich?

Lösung

Der Grund „& MyFrameGrabber :: HookFunction“ kann nicht auf eine BUF_HOOK_FUNCTION_PTR umgewandelt wird, ist, dass, wobei ein Mitglied der Klasse, es implizit als erster Parameter hat den „diesen“ Zeiger, so können Sie keine Member-Funktion in einem nicht konvertieren Member-Funktion: die beiden Signaturen gleich aussehen, sind aber tatsächlich unterschiedliche

.

Ich würde eine Schnittstelle erklären, die Funktion zu definieren aufrufen, haben Sie Ihre Klasse sie implementieren und das Objekt selbst, anstatt der Callback-Pass (können Sie als objektorientierte Schnittstelle denken Ersatz eines Funktionszeiger):

class IHookInterface{
public:
    virtual long HookFunction(long, long, void*) = 0;
};
 class HookClass : public IHookInterface{
public:
    virtual long Hook(long, long, void*) {
        // your code here... 
    }
};

// neue Definition: ThirdPartyGrab (..., IHookInterface, ...);

.

EDIT - andere mögliche Lösung, falls Sie die Bibliothek nicht ändern können: einen Singleton verwenden, anstatt eine statische Funktion

class HookClass{
public:
    static HookClass& instance(){
        static HookClass _instance;
        return _instance;
    }
    long Hook(long, long, void*) {
        // your code here... 
    }
};

long call_hook(long x,long y,void * z){
    return HookClass::instance().Hook(x,y,z);
}

ZWEITER EDIT: Sie könnten leicht die Singleton-Klasse mit einem Initialisierungsverfahren ändern Sie den Konstruktor mit den richtigen Parametern zu nennen, aber vielleicht ist es nicht eleganter als die folgende Lösung, die einfacher ist:

class HookClass{
public:

    HookClass(string x,string y...){
    }

    long Hook(long, long, void*) {
        // your code here... 
    }
};

static HookClass * hook_instance = 0;

long call_hook(long x,long y,void * z){
    if (0 != hook_instance){
        return hook_instance->Hook(x,y,z);
    }
}

int main(){
    hook_instance = new HookClass("x","y");
    ThirdPartyGrab(..., call_hook, ...);
}

Andere Tipps

Ihre private Member-Methode hat einen impliziten this Zeiger als erstes Argument. Wenn Sie das schreiben, es ist offensichtlich, dass die Funktionssignaturen nicht übereinstimmen.

Sie müssen eine statische Member-Funktion schreiben, die als Callback-Funktion in die Bibliothek übergeben werden können. Das letzte Argument der HookFunction, ein void*, sieht für mich sehr ähnlich wie ein Cookie, wo man die eigenen Zeiger in passieren kann.

Also, alles in allem sollte es so etwas wie diese:

class MyClass {
  long MyCallback(long, long) {
    // implement your callback code here
  }

  static long __stdcall ThirdPartyGrabCallback(long a, long b, void* self) {
    return reinterpret_cast<MyClass*>(self)->MyCallback(a, b);
  }
public:
  void StartGrab() {
    ThirdPartyGrab(..., &MyClass::ThirdPartyGrabCallback, ..., this, ...);
  }
};

Dies funktioniert natürlich nur, wenn das void* Argument tut, was ich sagte. Die Position des this im ThirdPartyGrab() Anruf sollte einfach zu finden, wenn Sie die komplette Funktionssignatur einschließlich den Parameternamen zur Verfügung zu haben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top