2014-12-01 10 views
1

mongoose (C 라이브러리)을 사용하여 작성한 서버를 C++ 클래스로 래핑하려고합니다. 문제는 몽구스로 서버의 인스턴스를 만드는 mg_create_server()ev_handler 함수를 전달하려고한다는 것입니다.캐스트 오류가 네임 스페이스가있는 void 함수를 전달하는 중

src/Server.cpp:16:44: error: cannot convert 'Server::ev_handler' from 
type 'int (Server::)(mg_connection*, mg_event)' to type 'mg_handler_t 
{aka int (*)(mg_connection*, mg_event)}' server = 
mg_create_server(NULL, ev_handler); 

내가 ev_handler 정적 만들려고하지만 ... 어떤 생각을 래퍼 클래스 내부에 있어야한다 send_index_page(conn)있다 :하지만이 캐스팅 오류가 나는 생각 주는가?

void Server::start() { 
     struct mg_server *server; 
     int numberOfObjects; 
     _application = new Application(); 
     _application->start(); 

     // Create and configure the server 
     server = mg_create_server(NULL, ev_handler); 

//... more code here ... 
} 

int Server::ev_handler(struct mg_connection *conn, enum mg_event ev) { 
       switch (ev) { 
         case MG_AUTH:  return MG_TRUE; 
         case MG_REQUEST: return send_index_page(conn); 
         default:   return MG_FALSE; 
       } 
} 
+1

제목에 "문제"를 언급 할 수없는 주위를 창의적으로 다루지 마십시오. * 문제 설명 *, 문제가 있다고 말하지 마십시오. (이것은 * 모두 * 여기에 문제가 있기 때문에 눈살을 찌푸리게합니다.) – usr2564301

답변

2

당신의 문제는 당신이 무료 함수 포인터를 원하는 매개 변수에 C++ 멤버 함수를 전달하고 있다는 것입니다.

몽구스는 C API이며 모든 콜백 매개 변수는 C++에서 자유 (멤버가 아닌) 함수 인 C 스타일 함수입니다.

멤버 함수 포인터는 호출하기 위해 메서드가 호출되는 개체 인 this이 필요하다는 점에서 자유 함수 포인터와 다릅니다.

귀하의 경우 Server 클래스에 멤버 함수 포인터를 전달하고 있습니다.

어떤 C API와 상호 작용할 때 void* 컨텍스트 개체를 전달한 다음 콜백에 전달합니다. 그런 다음 자유 함수 또는 정적 클래스 메소드 (this이 없으므로 C API에 대해 작업 할 수 있음)에 대한 포인터를 전달합니다. 콜백이 호출되면 컨텍스트 개체를 올바른 형식으로 캐스팅하고 멤버 함수를 호출하여 개체 컨텍스트로 돌아갑니다. 나는 몽구스에서 그러한 시설을 볼 수 없다. 어쩌면 그곳에있을 수 있고 나는 그것을 발견하지 못하고있을뿐입니다.

당신은 원래 몽구스 프로젝트는 C++와 더 잘 작동하도록 만들어 낸다 이미 exising 몽구스 C++ 시도 할 수 있습니다 : 클래스로 리디렉션, 당신은 정적 스텁을 사용한다 https://github.com/Gregwar/mongoose-cpp

+0

몽구스 - cpp를 보았지만 2 년전의 몽구스를 사용합니다. – mpromonet

2

콜백 정적 할 필요를 예.

server_param 속성에 클래스 인스턴스를 저장하면 mg_server을 정적 스텁에 다시 가져 와서이 인스턴스로 전달할 수 있습니다.

class Server 
{ 
public: 
     void start() { 
      mg_create_server(this, ev_handlerStub); 
     } 
     static int ev_handlerStub(struct mg_connection *conn, enum mg_event ev) { 
      ((Server*)conn->server_param)->ev_handler(conn, ev); 
     } 
     int ev_handler(struct mg_connection *conn, enum mg_event ev) { 
      // job to do with the class instance 
     } 
}; 

과 같이 진행, 그 ev_handler 방법 내부 클래스 인스턴스에 대한 액세스를 허용 :

이 같이 달성 될 수있다.