2017-11-01 4 views
0

일부 컨텍스트 : 기본 C++을 알고 있습니다. 처음으로 Visual Studio에서 C++/CLI를 사용하여 GUI 응용 프로그램을 만들려고합니다. 그러나, 나는 후자에 대해 많은 답변을 온라인으로 찾을 수 없습니다.C++/CLI의 스레드에 콜백 함수 전달

클래스에 도착했습니다 : MyForm, Windows Form에 해당하는 기본 클래스 및 OtherClass입니다. MyFormOtherClass 유형의 개체를 구성원으로 갖고 있습니다. MyForm의 기능은, 예 myButton_Click,이 객체를 초기화하고 스레드에서 그 기능 중 하나를 호출

using namespace System::Threading; 

ref class MyForm; 
ref class OtherClass; 

public ref class MyForm : public System::Windows::Forms::Form { 
    public: 

    //... 

    private: 
     OtherClass^ o; 

     System::Void myButton_Click(System::Object^ sender, System::EventArgs^ e) { 

      //When the button is clicked, start a thread with o->foo 
      o = gcnew OtherClass; 
      Thread^ testThread = gcnew Thread(gcnew ThreadStart(o, &OtherClass::foo)); 
      newThread->Start(); 

     } 



}; 

ref class OtherClass { 
    public: 
     void foo() { 
      //Do some work; 
     } 
}; 

이것은 지금까지 작동하는 것 같군. 내가 원하는 건 일이 foo의 값으로 UI를 업데이트하기 위해 어떤 종류의 콜백 함수를 MyClass에서 o->foo으로 전달하는 것입니다.

이 작업을 수행하는 가장 좋은 방법은 무엇입니까? CLI 때문에 단순히 함수 포인터를 전달하는 기능이 작동하지 않습니다.

+1

대부분의 경우 [위임] (https://msdn.microsoft.com/en-us/library/c320cx3h.aspx)? – orhtej2

+0

감사! 그 방법이 될 것 같습니다,하지만 여러 파일에 걸쳐 그들을 사용하는 방법을 찾을 수 없습니다. 두 헤더 파일에서 델리게이트를 선언하려고하면 재정의 오류 (duh)가 발생합니다. 파일 중 하나에서만 델리게이트를 선언하면 다른 파일에서 알 수없는 식별자 오류가 발생합니다. 그리고 그 파일에서 델리게이트를 전달 선언하는 방법이없는 것 같습니다. – jmb

+0

[이 답변] (https://stackoverflow.com/a/1147523/7034621) stdafx.h에서 대리자 선언을 제안합니다. – orhtej2

답변

0

나는 그것을 가지고있다. 그러나 @Hans Passant가 지적한 바와 같이, 이것은 거의 BackgroundWorker의 동작을 모방합니다. 어쨌든 BackgroundWorker을 사용하지 말고 가장 많이 묻는 질문에 대한 대답은 다음과 같습니다. 그것은 매우 깨끗하지 않다.


@ orhtej2가 가리키는대로, a delegate is what's needed. 그때 OtherClass의 생성자에 이러한 대리자를 통과

delegate void aFancyDelegate(System::String^); 

그래서 : 위의 헤더 파일을 모두가 인식하기 위해서는 다음과 같은 예를 들어, (here를 제안), 나는 stdafx.h의 대리자를 선언했다 MyForm 내의 객체 초기화 라인

aFancyDelegate^ del = gcnew aFancyDelegate(this, &MyForm::callbackFunction); 
o = gcnew OtherClass(del); 

o = gcnew OtherClass; 

변경. this answer에 제안

마지막으로, 그것은 다른 스레드에서 호출 된 경우에도 callbackFunction에서 UI 요소를 업데이트 할 수 있도록,이 같은 것을 포함했다 :

void callbackFunction(String^ msg) { 

      //Make sure were editing from the right thread 
      if (this->txtBox_Log->InvokeRequired) { 
       aFancyDelegate^ d = 
        gcnew aFancyDelegate(this, &MyForm::callbackFunction); 
       this->Invoke(d, gcnew array<Object^> { msg }); 
       return; 
      } 

      //Update the UI and stuff here. 
      //... 
     } 
+1

BackgroundWorker 클래스를 다시 발명하고 있습니다. 아무도 그것이 의도적인지는 알 수 없지만 정확하게 그럴 것 같지 않습니다. –

+0

전에 BackgroundWorker를 사용한 적이 없습니다. 고마워! – jmb

+0

업데이트 : BackgroundWorker가 내가 필요한 것입니다. 다시 한 번 감사드립니다! – jmb