首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从Windows类调用PThread到Windows类中的函数

从Windows类调用PThread到Windows类中的函数
EN

Stack Overflow用户
提问于 2012-03-31 11:54:40
回答 1查看 841关注 0票数 0

在VisualStudio2008Professional中,我在Windows窗体上使用p线程,但在示例源代码中显示的行中出现了错误。可能是因为它是C++/CLI,因为这通常适用于常规类。问题就在这一行上:

((TestGUI*)上下文)->TestxFunc();

在函数StaticCallFunc中

代码语言:javascript
复制
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’1>编译器上使用这个间接性,将'*‘替换为'^’以继续解析 错误C2227:'->TestxFunc‘的左边必须指向类/struct/union/泛型

我该怎么做才能解决这个问题?此调用通常在常规类上工作,但在Windows窗体中却不起作用

EN

Stack Overflow用户

回答已采纳

发布于 2012-03-31 16:15:02

因为TestGUI是一个CLI/C++类,所以您应该使用^ not *来取消对其指针的引用,但这并不是唯一的问题。您似乎希望在p线程中执行CLI/C++类成员方法。要使它工作,您可以尝试以下方法:

*从StaticCallFunc类中删除TestGUI并使其成为一个全局方法。

*要将TestGUI指针传递给非托管函数,可以使用gcroot。因此,定义一个容器类,例如PtrContainer,它将gcroot作为成员。

代码语言:javascript
复制
//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用作以下内容:

代码语言:javascript
复制
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)中的容器指针:

代码语言:javascript
复制
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组件时,您必须小心地以线程安全的方式调用控件。

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

代码语言:javascript
复制
//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;
}

编撰:

代码语言:javascript
复制
/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
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9955632

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档