By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,715 Members | 1,815 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,715 IT Pros & Developers. It's quick & easy.

.Net c++ multithreading using form1 generated code

P: 2
Hello all,

I am quite new to c++/. Net so please don't shoot me down for being a newbie. Any way I am trying to make a simple multithreading program that is just to learn the ideas behind it (before I incorporate them in another program). I just canít seem to get a non-static call to work in my thread that has access to the Form1 variables and controls I need. I can call a non-static function using another class but then I can seem to get in to link to Form1 without creating a new instance (I don't want that as then it will not really work).

Below is my code using VC++ Express Edition on win xp pro

Expand|Select|Wrap|Line Numbers
  1.  
  2. #pragma once
  3. #include "Thread.h"//test header class not used
  4. #include "stdafx.h"
  5. #include <process.h>//multi-threading
  6. #include <stdlib.h>
  7. #include "windows.h"//windpws commands
  8.  
  9. //multi-threading
  10. unsigned __stdcall MyThread1(void * param);
  11. unsigned tid1; // thread IDs
  12. HANDLE hMainThread; // thread handles
  13. HINSTANCE hInst; // instance handle
  14. HWND hwnd;
  15.  
  16. //namespace
  17. using namespace System;
  18. using namespace System::Windows;
  19. using namespace System::ComponentModel;
  20. using namespace System::Collections;
  21. using namespace System::Windows::Forms;
  22. using namespace System::Data;
  23. using namespace System::Drawing;
  24. #using <System.dll>
  25. #using <System.Drawing.dll>
  26. #using <System.Windows.Forms.dll>
  27.  
  28. namespace Multi_Thread_Test2 {
  29.  
  30.     #define  __stdcall
  31.  
  32.     using namespace System;
  33.     using namespace System::ComponentModel;
  34.     using namespace System::Collections;
  35.     using namespace System::Windows::Forms;
  36.     using namespace System::Data;
  37.     using namespace System::Drawing;
  38.  
  39.     public ref class Form1 : public System::Windows::Forms::Form
  40.     {
  41.     public:
  42.         Form1(void)
  43.         {
  44.             InitializeComponent();
  45.             //
  46.             //TODO: Add the constructor code here
  47.             //
  48.         }
  49.     public:
  50.         /// <summary>
  51.         /// Clean up any resources being used.
  52.         /// </summary>
  53.         ~Form1()
  54.         {
  55.             if (components)
  56.             {
  57.                 delete components;
  58.             }
  59.         }
  60.     public: System::Windows::Forms::Button^  Run;
  61.     public: System::Windows::Forms::ProgressBar^  ProgressBar;
  62.  
  63.     public:
  64.  
  65.         System::ComponentModel::Container ^components;
  66.  
  67. #pragma region Windows Form Designer generated code
  68.         /// <summary>
  69.         /// Required method for Designer support - do not modify
  70.         /// the contents of this method with the code editor.
  71.         /// </summary>
  72.         void InitializeComponent(void)
  73.         {
  74.             this->Run = (gcnew System::Windows::Forms::Button());
  75.             this->ProgressBar = (gcnew System::Windows::Forms::ProgressBar());
  76.             this->SuspendLayout();
  77.             // 
  78.             // Run
  79.             // 
  80.             this->Run->Location = System::Drawing::Point(202, 61);
  81.             this->Run->Name = L"Run";
  82.             this->Run->Size = System::Drawing::Size(75, 23);
  83.             this->Run->TabIndex = 0;
  84.             this->Run->Text = L"Run";
  85.             this->Run->UseVisualStyleBackColor = true;
  86.             this->Run->Click += gcnew System::EventHandler(this, &Form1::Run_Click);
  87.             // 
  88.             // ProgressBar
  89.             // 
  90.             this->ProgressBar->Location = System::Drawing::Point(13, 12);
  91.             this->ProgressBar->Name = L"ProgressBar";
  92.             this->ProgressBar->Size = System::Drawing::Size(450, 43);
  93.             this->ProgressBar->Step = 1;
  94.             this->ProgressBar->TabIndex = 1;
  95.             this->ProgressBar->Value = 1;
  96.             // 
  97.             // Form1
  98.             // 
  99.             this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
  100.             this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
  101.             this->ClientSize = System::Drawing::Size(475, 95);
  102.             this->Controls->Add(this->ProgressBar);
  103.             this->Controls->Add(this->Run);
  104.             this->Name = L"Form1";
  105.             this->Text = L"Form1";
  106.             this->ResumeLayout(false);
  107.  
  108.         }
  109. #pragma endregion
  110.     private: System::Void Run_Click(System::Object^  sender, System::EventArgs^  e)
  111.              {
  112.                 StartThreadFunc();
  113.              }
  114.     public: void UpdateProgressBar()
  115.              {
  116.                 int i;
  117.                 for (i=0;i<100;i++)
  118.                 {
  119.                     System::Threading::Thread::Sleep(500);
  120.                     this->ProgressBar->Value = i;
  121.                 }
  122.              }
  123.     public: void StartThreadFunc()
  124.             {
  125.             void ( *funcPtr)( ) =   &Multi_Thread_Test2::Form1::UpdateProgressBar; 
  126.              hMainThread = (HANDLE) _beginthreadex(NULL, 0, funcPtr, (void *) hwnd, 0, &tid1);
  127.             }
  128.  
  129.     };// end class Form1 definition        
  130. unsigned __stdcall MyThread1(void * param)//unused function
  131.              {    
  132.                 /*int i;
  133.                 for (i=0;i<100;i++)
  134.                 {
  135.                     System::Threading::Thread::Sleep(500);
  136.                     this->ProgressBar->Value = i;
  137.                 }*/
  138.                 /*Form1 MainForm;
  139.                 MainForm.UpdateProgressBar();*/
  140.                 return 0;
  141.              }
  142.  
  143. }//end multi_thread_test2
  144.  
  145.  
What i get as an output is

Expand|Select|Wrap|Line Numbers
  1. ------ Rebuild All started: Project: Multi_Thread_Test2, Configuration: Debug Win32 ------
  2. Deleting intermediate and output files for project 'Multi_Thread_Test2', configuration 'Debug|Win32'
  3. Compiling...
  4. stdafx.cpp
  5. Compiling...
  6. AssemblyInfo.cpp
  7. Multi_Thread_Test2.cpp
  8. c:\documents and settings\lspencer\my documents\visual studio 2005\projects\multi_thread_test2\multi_thread_test2\Form1.h(139) : error C3374: can't take address of 'Multi_Thread_Test2::Form1::UpdateProgressBar' unless creating delegate instance
  9. c:\documents and settings\lspencer\my documents\visual studio 2005\projects\multi_thread_test2\multi_thread_test2\Form1.h(140) : error C2665: '_beginthreadex' : none of the 2 overloads could convert all the argument types
  10.         C:\Program Files\Microsoft Visual Studio 8\VC\include\process.h(57): could be 'uintptr_t _beginthreadex(void *,unsigned int,unsigned int (__stdcall *)(void *),void *,unsigned int,unsigned int *)'
  11.         C:\Program Files\Microsoft Visual Studio 8\VC\include\process.h(67): or 'uintptr_t _beginthreadex(void *,unsigned int,unsigned int (__clrcall *)(void *),void *,unsigned int,unsigned int *)'
  12.         while trying to match the argument list '(int, int, void (__clrcall *)(void), void *, int, unsigned int *)'
  13. Generating Code...
  14. Build log was saved at "file://c:\Documents and Settings\lspencer\My Documents\Visual Studio 2005\Projects\Multi_Thread_Test2\Multi_Thread_Test2\Debug\BuildLog.htm"
  15. Multi_Thread_Test2 - 2 error(s), 0 warning(s)
  16. ========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
  17.  
  18.  
I now the problem lies with

Expand|Select|Wrap|Line Numbers
  1.  
  2. void ( *funcPtr)( ) =   &Multi_Thread_Test2::Form1::UpdateProgressBar; 
  3.              hMainThread = (HANDLE) _beginthreadex(NULL, 0, funcPtr, (void *) hwnd, 0, &tid1);
  4.  
  5.  
All help would be welcome. I have already tried using the CreateThread function to no luck.
Aug 6 '07 #1
Share this Question
Share on Google+
2 Replies


TRScheel
Expert 100+
P: 638
You are creating a native pointer to reference the function. You need to create a managed pointer to use it.

Managed pointers are declared with ^ instead of *


I explain it in more detail on this thread:

Thread Regarding Native/Managed Pointers
Aug 6 '07 #2

P: 2
i managed to fix it in the end via changing the code to use

using namespace System::Threading;

here it is, to help any one else

Expand|Select|Wrap|Line Numbers
  1.  
  2. #pragma once
  3.  
  4. namespace Multi_Thread_Test2 {
  5.  
  6.     using namespace System;
  7.     using namespace System::ComponentModel;
  8.     using namespace System::Collections;
  9.     using namespace System::Windows::Forms;
  10.     using namespace System::Data;
  11.     using namespace System::Drawing;
  12.     using namespace System::Threading;
  13.  
  14.     /// <summary>
  15.     /// Summary for Form1
  16.     ///
  17.     /// WARNING: If you change the name of this class, you will need to change the
  18.     ///          'Resource File Name' property for the managed resource compiler tool
  19.     ///          associated with all .resx files this class depends on.  Otherwise,
  20.     ///          the designers will not be able to interact properly with localized
  21.     ///          resources associated with this form.
  22.     /// </summary>
  23.     public ref class Form1 : public System::Windows::Forms::Form
  24.     {
  25.     public:Form1(void)
  26.         {
  27.             InitializeComponent();
  28.         }    
  29.     public:~Form1()
  30.         {
  31.             if (trd->IsAlive)
  32.                 trd->Abort();
  33.             if (components)
  34.             {
  35.                 delete components;
  36.             }
  37.         }    
  38.     private: Thread ^trd;
  39.     public: System::Windows::Forms::Button^  Run;
  40.     public: System::Windows::Forms::ProgressBar^  ProgressBar;
  41.     public:    System::ComponentModel::Container ^components;
  42.     #pragma region Windows Form Designer generated code
  43.             /// <summary>
  44.             /// Required method for Designer support - do not modify
  45.             /// the contents of this method with the code editor.
  46.             /// </summary>
  47.             void InitializeComponent(void)
  48.             {
  49.                 this->Run = (gcnew System::Windows::Forms::Button());
  50.                 this->ProgressBar = (gcnew System::Windows::Forms::ProgressBar());
  51.                 this->SuspendLayout();
  52.                 // 
  53.                 // Run
  54.                 // 
  55.                 this->Run->Location = System::Drawing::Point(202, 61);
  56.                 this->Run->Name = L"Run";
  57.                 this->Run->Size = System::Drawing::Size(75, 23);
  58.                 this->Run->TabIndex = 0;
  59.                 this->Run->Text = L"Run";
  60.                 this->Run->UseVisualStyleBackColor = true;
  61.                 this->Run->Click += gcnew System::EventHandler(this, &Form1::Run_Click);
  62.                 // 
  63.                 // ProgressBar
  64.                 // 
  65.                 this->ProgressBar->Location = System::Drawing::Point(13, 12);
  66.                 this->ProgressBar->Name = L"ProgressBar";
  67.                 this->ProgressBar->Size = System::Drawing::Size(450, 43);
  68.                 this->ProgressBar->Step = 1;
  69.                 this->ProgressBar->TabIndex = 1;
  70.                 this->ProgressBar->Value = 0;
  71.                 // 
  72.                 // Form1
  73.                 // 
  74.                 this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
  75.                 this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
  76.                 this->ClientSize = System::Drawing::Size(475, 95);
  77.                 this->Controls->Add(this->ProgressBar);
  78.                 this->Controls->Add(this->Run);
  79.                 this->Name = L"Form1";
  80.                 this->Text = L"Form1";
  81.                 this->ResumeLayout(false);
  82.  
  83.             }
  84. #pragma endregion
  85.     private: System::Void Run_Click(System::Object^  sender, System::EventArgs^  e)
  86.              {
  87.  
  88.                 StartThreadFunc();
  89.              }
  90.  
  91.     public:  void UpdateProgressBar()
  92.              {
  93.                 int i;
  94.                 for (i=0;i<100;i++)
  95.                 {
  96.                     System::Threading::Thread::Sleep(500);
  97.                     this->ProgressBar->Value = i;
  98.                 }    
  99.              }
  100.     public: void StartThreadFunc()
  101.             {
  102.                 ThreadStart ^myThreadDelegate = gcnew ThreadStart(this, &Form1::UpdateProgressBar);
  103.                 trd = gcnew Thread(myThreadDelegate);
  104.                 trd->IsBackground = true;
  105.                 trd->Start();
  106.             }
  107.  
  108.     };// end class Form1 definition    
  109. }//end multi_thread_test2
  110.  
  111.  
I tried to use the ^ pointer but i kept getting two linking errors, oh well this method works fine.
Aug 7 '07 #3

Post your reply

Sign in to post your reply or Sign up for a free account.