2012-01-04 4 views
2

Windows 소켓을 사용하여 서버와 클라이언트 간의 프록시로 작동하는 간단한 콘솔 응용 프로그램을 작성했습니다. 필자는 모든 in/outgoing 패킷을 실시간으로보기위한 그래픽 인터페이스를 만들기로 결정했습니다 (아주 간단한 wireshark처럼).C++ 다중 스레드 창 GUI (양식 액세스)

서버와 클라이언트 간의 연결은 메시지 루프와 다른 스레드에서 실행됩니다. 서버/클라이언트가 패킷을 보낼 때, 나는 그것을 (예를 들어 단순한 텍스트 컨트롤에 추가하는 것과 같이) 즉시 표시하고 싶습니다.

하지만 메시지 루프가없는 스레드보다 다른 스레드에서 양식에 액세스 할 수 없기 때문에이를 처리하는 방법을 모릅니다.

내가 여러 솔루션을 발견했습니다 - C++/CLI - - C#을 하지만 모든 .NET 플랫폼을 사용하지 않고 ++ C 관리. (정말이 GUI 주제에 익숙하지 않아도 .NET없이 윈도우 폼을 사용할 수 있는지 확실하지 않습니다.)

QT + C++이이 문제를 처리 할 수 ​​있습니까? 그렇지 않다면 네이티브 C++ 코드의 C#/Java에서 래퍼를 작성할 수 있습니까?

GUI를 사용하는 C/C++로 작성된 많은 응용 프로그램이 있어야합니다. 일반적인 방법은 무엇입니까?

+1

보조 스레드의 대화 상자에 맞춤 메시지를 게시하십시오. – ildjarn

답변

2

다른 스레드의 창에 액세스 할 수 없다는 것은 틀림 없습니다. PostMessage Win32 API 명령을 사용하여 메시지를 게시하기 위해이를 처리하는 적절한 방법 (또는 Win32를 둘러싼 랩퍼 라이브러리를 사용하는 경우 결국 해당 Postfix에서 호출하는 랩퍼의 모든 기능). 다음은 메시지 대기열과 관련된 Microsoft의 유용한 링크입니다. http://msdn.microsoft.com/en-us/library/windows/desktop/ms644928(v=vs.85).aspx

+0

+1 PostMessage() –

0

빠르고 유익한 Win32 솔루션에는 UI 섹션에 임계 구역, 텍스트 버퍼 및 타이머가 포함됩니다.

몇 전역을 정의

...

void onTimer() 
{ 
    if (overflow) 
    { 
      // handle this 
    } 
    else 
    if (newdata) // new data to display 
    { 
      // take the lock, copy the data and release the lock quickly 
      EnterCriticalSection(&bufferLock); 
      int dataread = newdata; 
      memcpy(uiDataBuffer, dataBuffer, dataread); 
      newdata = 0; 
      LeaveCriticalSection(&bufferLock); 

      // TODO: append the text in uiDataBuffer[] to your text control 
    } 
} 

는 작업자 스레드에서 호출 할

CRITICAL_SECTION bufferLock; // critical section (to be initialized somewhere) 
char dataBuffer[65536]; // contains the data that will be sent to the form 
int newdata = 0; // how much data we got (this variable must be atomic, int is ok) 
char uiDataBuffer[65536]; // data available to the form 
int overflow = 0; // just in case... 

UI 스레드 타이머 : 검증되지 않은

void sendData (char* data, int size) 
{ 
    EnterCriticalSection (&bufferLock); 
    if(size+newdata > 65536) 
     overflow = 1; 
    else 
    { 
     memcpy(dataBuffer+newdata, data, size); 
     newdata += size; 
    } 
    LeaveCriticalSection (&bufferLock); 
} 

코드입니다. 버퍼 크기 및 타이머 빈도를 조정해야합니다.

PostMessage() (사용자 지정 메시지 사용)를 사용하여 새 데이터를 사용할 수 있음을 UI에 알리기 위해 타이머를 사용하여 버퍼를 폴링하는 것을 피할 수 있습니다.

성능이 문제가되면 잠금없는 FIFO 대기열을 사용하여 생산자와 소비자 스레드 간의 데이터 교환을 매우 효율적으로 수행 할 수 있습니다.

PostMessage() 혼자 은 스레드 간 데이터 교환을위한 해결책이 아닙니다.

+0

두 답 모두 정말 도움이되었습니다. 감사합니다. 맞춤 메시지를 사용하는 우아한 방법이 있습니까? (나는 사용자 지정 메시지를 사용하는 경우 PACKET_ARRIVED가되도록 지정합니다. int 유형이어야합니다. 값이 다른 상수와 충돌하지 않는지 확인하는 방법 "간단히"충분히 큰 숫자를 사용해야합니까? 충돌을 피하기 위해 – user1131015

+0

WM_USER + something 시도 – rkosegi

+0

RegisterWindowMessage()를 사용하여 고유 한 "사용자 지정"메시지를 얻습니다. – al01

1

순수한 C++ GUI 라이브러리 인 Nana C++ Library (http://stdex.sourceforge.net)라는 무료 및 오픈 소스 대체 라이브러리가 있습니다. Nana 라이브러리를 사용하면 멀티 스레딩 문제를 쉽게 해결할 수 있습니다. GUI의 멀티 스레딩에 an article이 있습니다. 취미 프로젝트를위한 선택 일 것입니다.