How to Pass an object to a TThread function in C++?

79 views Asked by At

How can I pass an object to a TThread function? This is code based on an example that I found. It compiled and ran successfully until I added Synchronize(OutputString…).

I’m inputting a string from a TEdit in Form1 and trying to output it to another TEdit in Form1. The error message is :

[bcc32c Error] Unit2.cpp(60): no matching member function for call to 'Synchronize'.

This is the TThread code:

//---------------------------------------------------------------------------

#include <System.hpp>
#pragma hdrstop

#include "Unit2.h"
#include "Unit1.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------

//   Important: Methods and properties of objects in VCL can only be
//   used in a method called using Synchronize, for example:
//
//      Synchronize(&UpdateCaption);
//
//   where UpdateCaption could look like:
//
    void __fastcall TSortThread::UpdateCaption()
    {
        Form1->Button1->Caption = "Done!";
    }

    void __fastcall TSortThread::OutputString(wchar_t *string)
    {
        Form1->Edit2->Text = string;
    }
//---------------------------------------------------------------------------

__fastcall TSortThread::TSortThread(bool CreateSuspended)
    : TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------
void __fastcall TSortThread::Execute()
{
    NameThreadForDebugging(System::String(L"SortingThread"));
    //---- Place thread code here ----

    FreeOnTerminate = true;

    for(int i=0;i<50000 - 1;++i)  {

        for(int j=0;j<50000 - 1 - i;++j)  {

            if(Form1->dataField[j] > Form1->dataField[j+1]) {

                int temp = Form1->dataField[j];
                Form1->dataField[j] = Form1->dataField[j+1];
                Form1->dataField[j+1] = temp;
            }
        }
    }

    Synchronize(UpdateCaption);

    // input and output string
    wchar_t inputString[100];
    wcscpy(inputString,Form1->Edit1->Text.c_str());

    Synchronize(OutputString(inputString)); // COMPILE ERROR
}
//---------------------------------------------------------------------------

This is the header file:

//---------------------------------------------------------------------------

#ifndef Unit2H
#define Unit2H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
//---------------------------------------------------------------------------
class TSortThread : public TThread
{
protected:
    void __fastcall Execute();
public:
    __fastcall TSortThread(bool CreateSuspended);
    void __fastcall UpdateCaption();
  void __fastcall OutputString(wchar_t *string);
};
//---------------------------------------------------------------------------
#endif
2

There are 2 answers

2
CITBL On BEST ANSWER

// Important: Methods and properties of objects in VCL can only be
// used in a method called using Synchronize

But you are accessing "properties of objects in VCL" in Execute without Synchronize. I mean the Form1 object and its properties.

2.

Regarding your question. You can create a member variable of type wchar_t[] (or some other type) in your TSortThread class. Assign it a needed value before invoking Synchronize(OutputString). I.e. pass a value through a member variable, not through a method parameter, and use it inside OutputString

0
Remy Lebeau On

The version of TThread::Synchronize() that you are trying to call requires a class instance method that takes no parameters and returns nothing. But your OutputString() method takes a parameter, so it can't be passed to Synchronize().

As such, you will have to store your input string in a data member of your TSortThread class, and have OutputString() use that member, eg:

class TSortThread : public TThread
{
//...
private:
    String FInputString;
    void __fastcall GetInputString();
    void __fastcall OutputString();
//...
};
void __fastcall TSortThread::GetInputString()
{
    FInputString = Form1->Edit1->Text;
}

void __fastcall TSortThread::OutputString()
{
    Form1->Edit2->Text = FInputString;
}

void __fastcall TSortThread::Execute()
{
    //...
    Synchronize(GetInputString);
    Synchronize(OutputString);
    //...
}

That being said, if you are using one of the Clang-based compilers, TThread::Synchronize() will also accept a C++ lambda instead, eg:

void __fastcall TSortThread::Execute()
{
    //...
    String InputString;
    Synchronize([&](){ InputString = Form1->Edit1->Text });
    Synchronize([&](){ Form1->Edit2->Text = InputString });
    //...
}