将Windows窗体类中的PThread调用到Windows窗体类中的函数 [英] Calling PThread from Windows Form Class to a function inside the Windows Form Class

查看:210
本文介绍了将Windows窗体类中的PThread调用到Windows窗体类中的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Visual Studio 2008 Professional的Windows窗体中使用pthread,但我得到的错误在我在示例源中显示的行。可能是因为它是C ++ / CLI,因为这通常工作在常规类。问题出在这一行:

I'm using pthread on Windows Form in Visual Studio 2008 Professional, But I'm getting the error in the line that I show in the example source. Probably because it's C++/CLI because this usually work in regular classes. The problem is in this line:


(TestGUI *)context - > TestxFunc();

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

在函数StaticCallFunc中

in the function 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:'':不能在类型'Test :: TestxFunc'上使用此间接'>
编译器将'*'替换为'^'以继续解析

error C3699: '' : cannot use this indirection on type 'Test::TestxFunc' 1> compiler replacing '*' with '^' to continue parsing

错误C2227:' - > TestxFunc'的左侧必须指向
class / struct / union / generic type

error C2227: left of '->TestxFunc' must point to class/struct/union/generic type

我该如何解决这个问题?这个调用通常工作在正常的类,但在Windows窗体中它真的不

what do I do to fix this? This call usually work on regular classes, but inside the Windows Form it really doesn't

推荐答案

TestGUI 是一个CLI / C ++类,你应该使用 ^ 不是 * 它的指针,但这不是唯一的问题。看来你想在pthread中执行一个CLI / C ++类的成员方法。要使其工作,您可以尝试以下方式:

Since TestGUI is a CLI/C++ class, you should use the ^ not * to dereference its pointer, but thats not the only problem. It seems you want to execute a CLI/C++ class member method in a pthread. To make it work, you can try the following way:

*从<$ c删除 StaticCallFunc $ c> TestGUI 类并使其成为一个全局方法。

*要通过 TestGUI 指向非托管函数,使用 gcroot 。所以定义一个容器类。 PtrContainer 作为成员拥有 gcroot

*Remove StaticCallFunc from TestGUI class and make it a global method.
*To pass TestGUI pointer to an unmanaged function you can use gcroot. So define a container class e.g. PtrContainer which has gcroot as a member.

//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 如下:

When you bind to pthread_create you can use PtrContainer as the following:

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 );
}

您应该删除驱动程序中的容器指针c> StaticCallFunc(void cClientFunc c>);

And you should delete the container pointer inside the driver method (StaticCallFunc) after you have done with it:

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组件时,您必须小心地以线程安全的方式调用您的控件。

One more note; when you are accessing a .NET gui component in a multithread way, you must be careful to make calls to your controls in a thread-safe way.



编辑:我有添加了以下完整的源代码,它在Visual Studio 11,Windows7下编译和工作。


I have added the following complete source code which compiles and works under 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 

这篇关于将Windows窗体类中的PThread调用到Windows窗体类中的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆