从Windows窗体类调用PThread到Windows窗体类内的函数
Calling PThread from Windows Form Class to a function inside the Windows Form Class
我在Visual Studio 2008 Professional的Windows窗体上使用pthread,但在示例源代码中显示的行中出现错误。可能是因为它是C++/CLI,因为它通常在常规类中工作。问题出在这一行:
((TestGUI*)上下文)->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:":无法对类型"Test::TestxFunc"1>使用此间接寻址编译器将"*"替换为"^"以继续分析
错误C2227:"->TestxFunc"的左侧必须指向类/结构/联合/通用类型
我该怎么办才能解决这个问题?这个调用通常适用于常规类,但在Windows窗体中它实际上不适用于
由于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组件时,必须小心以线程安全的方式调用控件。
编辑:我添加了以下完整的源代码,它在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 AssembliesMicrosoftFramework.NETFrameworkv4.0mscorlib.dll" /FU"C:Program Files (x86)Reference AssembliesMicrosoftFramework.NETFrameworkv4.0System.dll" /FU"C:Program Files (x86)Reference AssembliesMicrosoftFramework.NETFrameworkv4.0System.Windows.Forms.dll" /Zc:forScope /Fo".Debug" /Gy- /Fp".DebugDebug.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窗体应用程序中打开txt文件并将行导入文本框
- 我可以在 vb.net Windows 窗体应用程序中使用 COLECONTROLModule 吗?
- std::线程在 Windows 窗体中不可用
- 无法在 Visual Studio 2015 中创建 Windows 窗体
- 如何在 Windows 窗体应用程序 (C++) 中使用固定宽度整数
- Windows窗体应用程序无法播放视频[VLC ActiveX插件和IE Web插件v2]
- Windows窗体作为非托管应用程序的子窗口
- 生成窗体的控制台应用程序(Windows窗体)
- 何时销毁 Windows 窗体数据源
- 文本框为空时,C++Windows窗体应用程序出现未处理的异常错误
- 文本框为空时C++ Windows 窗体应用程序未处理的异常错误
- C++ Windows 应用程序窗体无法进行前向声明
- 是Windows窗体应用程序(在visual studio c++中)自动c++/CLI
- 如何检查是否所有字段都已填写?[C++,VS 2015,Windows窗体]
- 使用Visual Studio c++的Windows窗体应用程序,该应用程序链接到CUDA项目
- 使用windows窗体在richtextbox中设置斜体的示例
- 在 Windows 窗体中使用 C++ 类会导致 System.AccessViolationException
- 可视化如何将项目 win32 控制台应用程序转换为C++ Windows 窗体
- DDX 数据绑定与 Windows 窗体找不到类方法
- 在调用不同类的函数时刷新 Windows 窗体