2017-06-23 46 views
0

我創建了一個名爲InputControl的類。我正在使用名爲GLFW的庫和函數glfwSetKeyCallback。該函數被定義爲:作爲函數指針傳入C++方法?

GLFWkeyfun glfwSetKeyCallback(GLFWwindow *窗口,GLFWkeyfun cbfun)

的typedef如下:

無效的typedef(* GLFWkeyfun)(GLFWwindow *,INT ,int,int,int)

問題是我無法將我的方法轉換爲函數指針。我覺得我試圖以各種可能的方式施展它。我不知道我還需要怎樣施放這種方法。有沒有特定的方法將相關方法作爲函數指針傳遞? 我的代碼如下:

#pragma once 
#include <GLFW/glfw3.h> 
#include "config.h" 

class InputControl { 
public: 
    void bind(); 
    void unbind(); 

private: 
    void __glfw__keycallback_bind(GLFWwindow* window, int key, int scancode, int action, int mods); 
}; 

InputControl.cpp

void InputControl::bind() { 
    glfwSetKeyCallback(__application__window, __glfw__keycallback_bind); 
} 

void InputControl::unbind() { 

} 

void InputControl::__glfw__keycallback_bind(GLFWwindow * window, int key, int scancode, int action, int mods) { 
//... other code here 
} 

Visual Studio中給了我下面的錯誤類型爲void(InputControl :: *)的」

E0167參數( GLFWwindow * window,int key,int scancode,int action,int mods)「與參數類型」GLFWkeyfun「不兼容

+4

這是不可能的非靜態類方法的指針轉換爲常規函數指針。這些是完全不同和不相容的實體。只要停止嘗試這樣做。不幸的是,你的問題沒有提供足夠的背景來提供替代解決方案。實際的'InputControl'對象在哪裏? – AnT

+5

與您的問題無關,但不要使用兩個前導下劃線定義名稱或符號。這些保留給所有範圍內的編譯器和標準庫。請參閱[這個老問題和它的答案](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier)瞭解更多信息。 –

+0

擴展@ AnT的評論。一個方法作用於***的一個實例***。常規函數無法確定要執行哪個實例。 –

回答

3

非靜態成員函數需要一個對象來處理。您需要一個非成員函數或靜態成員函數作爲回調。如果你確實需要訪問InputControl類的一個實例回調裏面,你可以使用glfwSetWindowUserPointer()設置窗口的用戶指針,然後回調可以使用該指針調用非靜態成員函數:

class InputControl { 
public: 
    void bind(); 
    void unbind(); 

private: 
    static void keyCallbackStatic(GLFWwindow* window, 
            int key, 
            int scancode, 
            int action, 
            int mods); 
    void keyCallback(GLFWwindow* window, 
         int key, 
         int scancode, 
         int action, 
         int mods); 
}; 

void InputControl::bind() { 
    glfwSetWindowUserPointer(applicationWindow, this); 
    glfwSetKeyCallback(applicationWindow, keyCallbackStatic); 
} 

void InputControl::keyCallbackStatic(GLFWwindow* window, 
            int key, 
            int scancode, 
            int action, 
            int mods) 
{ 
    InputControl* that = static_cast<InputControl*>(glfwGetWindowUserPointer(window)); 
    that->keyCallback(window, key, scancode, action, mods); 
} 

void InputControl::keyCallback(GLFWwindow* window, 
           int key, 
           int scancode, 
           int action, 
           int mods) 
{ 
    // Do whatever 
} 

您需要確保您的對象始終保持活動狀態,只要您的窗口處於活動狀態,並且沒有其他任何操作將窗口的用戶指針設置爲除對象指針之外的任何其他內容。

+1

你打敗了我。我正要發佈相同的答案;-) –

0

你可以有一個調用你的成員函數的接口:

class App { 
public: 
    void onKeyDown(int key, int action) { 
     if (action == 1) 
      std::cout << "Pressed: " << static_cast<char>(key) << '\n'; 
     if (action == 0) 
      std::cout << "Released: " << static_cast<char>(key) << '\n'; 
    } 
}; 

class Interface { 
public: 
    static void* p; 

    static void OnKeyDown(GLFWwindow * window, int key, int scancode, int action, int mods) { 
     ((App*)(p))->onKeyDown(key, action); 
    } 
}; 
void * Interface::p; 

int main() 
{ 
    App app; 

    [...] 

    glfwSetKeyCallback(window, Interface::OnKeyDown); 

}