2012-03-31 60 views
0

我在Visual Studio 2008 Professional的Windows窗體上使用pthread,但是我在示例源中顯示的行中出現錯誤。可能是因爲它是C++/CLI,因爲這通常在常規類中工作。問題出現在這一行:從Windows窗體類調用PThread到Windows窗體類中的函數

((TestGUI *)context) - > TestxFunc();

在功能StaticCallFunc

public ref class TestGUI : public System::Windows::Forms::Form { 
     /... 
    public: 

void TestxFunc(std::string test, std::string test2){ 
     this->btn_next->Enabled = false; 
     cout << "HI, Test: " << test << "," << " Test 2: " << test2 << endl; 

} 

static void *StaticCallFunc(void *context){ 
    std::string test = "foo"; 
    std::string test2 = "bar"; 
    printf("\nStarting Thread"); 
    ((TestGUI*)context)->TestxFunc(); //Line with the error down. 
    return 0; 

} 

System::Void tester_Click(System::Object^ sender, System::EventArgs^ e) { 
     pthread_t t; 
     pthread_create(&t, NULL, &TestGUI::StaticCallFunc, this); 
} 

//... 

錯誤C3699: '':上式不能使用此間接 '測試:: TestxFunc' 1> 編譯器替換 '*' 與 '^',以繼續解析

錯誤C2227:左 ' - > TestxFunc' 必須指向 類/結構/聯合/通用型

我該如何解決這個問題?此調用通常在普通班工作,但Windows窗體裏面確實沒有

回答

0

由於TestGUI是一個CLI/C++類,你應該使用^*取消引用它的指針,但那不是唯一的問題。看來你想在一個pthread中執行一個CLI/C++類的成員方法。要使其工作,您可以嘗試以下方法:

*從TestGUI類中刪除StaticCallFunc並使其成爲全局方法。
*要將TestGUI指針傳遞給非託管函數,您可以使用gcroot。因此定義一個容器類,例如PtrContainer其中gcroot作爲成員。

//dont forget forward declerations 
void *StaticCallFunc(void *context); //forward decleration 
ref class TestGUI; //forward decleration 

//Define a simple argument class to pass pthread_create 
struct PtrContainer{ 
    gcroot<TestGUI^> guiPtr; //you need to include vcclr.h for this 
}; 

當您綁定到pthread_create你可以使用PtrContainer如下所示:

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

    //init. container pointer, 
    //we use dynamically allocated object because the thread may use it after this method return 
    PtrContainer* ptr = new PtrContainer; 
    ptr->guiPtr = this; 

    pthread_t t; 
    pthread_create(&t, NULL, StaticCallFunc, ptr); 
} 

你應該刪除你用它做後駕駛方法(StaticCallFunc)容器內部指針:

void *StaticCallFunc(void *context){ 
    std::string test = "foo"; 
    std::string test2 = "bar"; 
    printf("\nStarting Thread"); 
    PtrContainer* ptr = reinterpret_cast<PtrContainer*>(context); 
    ptr->guiPtr->TestxFunc(test, test2); 

    //dont forget to delete the container ptr. 
    delete ptr; 

    return 0; 
} 

還要說明;當您正在訪問的多線程方式.NET GUI組件,you must be careful to make calls to your controls in a thread-safe way.


編輯:我已經添加了編譯和Visual Studio 11,Windows7的下工作以下完整的源代碼。

//sample.cpp 

#include <iostream> 
#include <string> 
#include <vcclr.h> 
#include <sstream> 
using namespace std; 
using namespace System; 
using namespace System::Windows::Forms; 

#include "pthread.h" 
#include <stdio.h> 

#define PTW32_THREAD_NULL_ID {NULL,0} 
#define int64_t _int64 

void *StaticCallFunc(void *context); //forward decleration 
ref class TestGUI; //forward decleration 

//Define a simple argument class to pass pthread_create 
struct PtrContainer{ 
    gcroot<TestGUI^> guiPtr; //you need to include vcclr.h for this 
}; 

ref class TestGUI : public System::Windows::Forms::Form 
{ 
public: 
    TestGUI(void) { 
     this->Click += gcnew System::EventHandler(this, &TestGUI::tester_Click); 
    } 

    void TestxFunc(std::string test, std::string test2){ 
      cout << "HI, Test: " << test << "," << " Test 2: " << test2 << endl; 
    } 

    System::Void tester_Click(System::Object^ sender, System::EventArgs^ e) { 
     //init. container pointer, 
     //we use dynamically allocated object because the thread may use it after this method return 
     PtrContainer* ptr = new PtrContainer; 
     ptr->guiPtr = this; 

     pthread_t t; 
     pthread_create(&t, NULL, StaticCallFunc, ptr); 
    } 
}; 

void *StaticCallFunc(void *context){ 
    std::string test = "foo"; 
    std::string test2 = "bar"; 
    printf("\nStarting Thread"); 
    PtrContainer* ptr = reinterpret_cast<PtrContainer*>(context); 
    ptr->guiPtr->TestxFunc(test, test2); 

    //dont forget to delete the container ptr. 
    delete ptr; 
    return 0; 
} 

int main() 
{ 
    TestGUI^ testGui = gcnew TestGUI(); 
    testGui->ShowDialog(); 
    return 0; 
} 

編譯時:

/analyze- /clr /Od /nologo /MDd /Gm- /Fa".\Debug\" /I".." /Oy- /FU"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll" /FU"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll" /FU"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Windows.Forms.dll" /Zc:forScope /Fo".\Debug\" /Gy- /Fp".\Debug\Debug.pch" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "CLEANUP_C" /D "_VC80_UPGRADE=0x0600" /D "_MBCS" /WX /errorReport:queue /GS /Fd".\Debug\" /fp:precise /FR".\Debug\" /W3 /Z7 /Zc:wchar_t /EHa 
+0

我測試自己,但我得到了在有線上的錯誤 「ptr-> guiPtr =本;」說 - >錯誤C2679:二進制'=':找不到操作符,它需要一個 – Grego 2012-03-31 18:42:18

+0

類型的右手操作數@Grego我已經添加完整的源文件,但我測試了只有我有VS 11 Beta。 – xaero99 2012-03-31 21:58:11