Embarcadero TThread:在 C++ 中传递 TThreadMethod
Embarcadero TThread: Pass TThreadMethod in C++
编辑:
现在我对正在发生的事情有了更好的了解,我想我可以更好地表达这个问题,这样它就更有用了。
我正在尝试在 C++ 中复制以下 delphi 代码
TThread.Queue(nil,
procedure
begin
LogMessage("test");
end
);
代码的目的是调用一种方法,以线程安全的方式更新表单上的 TMemo
。这是我尝试使用 Thread.Queue
调用的方法的 C++ 版本
void __fastcall TClientForm::LogMessage( String message )
{
MemoLog->Lines->Add( message );
}
因为我使用的是没有 CLANG 增强功能的 BCC32 编译器,所以不能选择使用 Lambda。相反,根据 this documentation,我需要创建一个继承自 TThreadProcedure
的 class,它会覆盖 Invoke()
方法来完成我需要完成的工作。然后我可以将 class 的一个实例传递给 TThread::Queue
。
我创建了以下 class,它继承了 TThreadProcuedure
并包含一个调用方法。
class TMyThreadProcedure : TThreadProcedure
{
void __fastcall Invoke( String message );
};
但是,由于 TThreadProcedure
是一个抽象 class,我不能简单地创建它的一个实例来传递给 TThread::Queue
。当我将 class 的实例传递给 TThread::Queue
时,从 TThreadProcedure
继承并定义要调用的函数的正确方法是什么?
如文档中所述:
How to Handle Delphi Anonymous Methods in C++
你有两个选择:
派生一个 class 1 实现适当的接口(在这种情况下,Classes::TThreadProcedure
),覆盖 Invoke()
方法来完成您想要的工作。然后,您可以将 class 的一个实例传递给 TThread::Queue()
。例如:
class TLogMessageRef : public TCppInterfacedObject<Classes::TThreadProcedure>
{
private:
TClientForm *form;
public:
TLogMessageRef(TClientForm* _form) : form(_form) {}
INTFOBJECT_IMPL_IUNKNOWN(TInterfacedObject);
void __fastcall Invoke()
{
form->LogMessage("test");
}
};
TThread::Queue(NULL,
Classes::_di_TThreadProcedure(
new TLogMessageRef(this)
)
);
(1的使用TCppInterfacedObject
and INTFOBJECT_IMPL_IUNKNOWN
is covered elsewhere in the documentation: Inheritance and Interfaces)
文档还提供了一个可重用的 TMethodRef
class 来帮助实现,如果您需要在代码的多个地方使用匿名 methods/procedures:
Using a Functor (Function Object)
例如:
struct LogMsg
{
TClientForm* form;
LogMsg(TClientForm *_form) : form(_form) {}
void operator()()
{
form->LogMessage("test");
}
};
typedef TMethodRef<Classes::TThreadProcedure, LogMsg, void> MyMethRef;
TThread::Queue(NULL,
Classes::_di_TThreadProcedure(
new MyMethRef(
LogMsg(this)
)
)
);
仅在 Clang-based C++11 compilers 中,您可以在任何需要匿名 procedure/method 的地方使用 C++ lambda:
TThread::Queue(NULL,
[this]() -> void { LogMessage("test"); }
);
编辑: 现在我对正在发生的事情有了更好的了解,我想我可以更好地表达这个问题,这样它就更有用了。
我正在尝试在 C++ 中复制以下 delphi 代码
TThread.Queue(nil,
procedure
begin
LogMessage("test");
end
);
代码的目的是调用一种方法,以线程安全的方式更新表单上的 TMemo
。这是我尝试使用 Thread.Queue
void __fastcall TClientForm::LogMessage( String message )
{
MemoLog->Lines->Add( message );
}
因为我使用的是没有 CLANG 增强功能的 BCC32 编译器,所以不能选择使用 Lambda。相反,根据 this documentation,我需要创建一个继承自 TThreadProcedure
的 class,它会覆盖 Invoke()
方法来完成我需要完成的工作。然后我可以将 class 的一个实例传递给 TThread::Queue
。
我创建了以下 class,它继承了 TThreadProcuedure
并包含一个调用方法。
class TMyThreadProcedure : TThreadProcedure
{
void __fastcall Invoke( String message );
};
但是,由于 TThreadProcedure
是一个抽象 class,我不能简单地创建它的一个实例来传递给 TThread::Queue
。当我将 class 的实例传递给 TThread::Queue
时,从 TThreadProcedure
继承并定义要调用的函数的正确方法是什么?
如文档中所述:
How to Handle Delphi Anonymous Methods in C++
你有两个选择:
派生一个 class 1 实现适当的接口(在这种情况下,
Classes::TThreadProcedure
),覆盖Invoke()
方法来完成您想要的工作。然后,您可以将 class 的一个实例传递给TThread::Queue()
。例如:class TLogMessageRef : public TCppInterfacedObject<Classes::TThreadProcedure> { private: TClientForm *form; public: TLogMessageRef(TClientForm* _form) : form(_form) {} INTFOBJECT_IMPL_IUNKNOWN(TInterfacedObject); void __fastcall Invoke() { form->LogMessage("test"); } }; TThread::Queue(NULL, Classes::_di_TThreadProcedure( new TLogMessageRef(this) ) );
(1的使用
TCppInterfacedObject
andINTFOBJECT_IMPL_IUNKNOWN
is covered elsewhere in the documentation: Inheritance and Interfaces)文档还提供了一个可重用的
TMethodRef
class 来帮助实现,如果您需要在代码的多个地方使用匿名 methods/procedures:Using a Functor (Function Object)
例如:
struct LogMsg { TClientForm* form; LogMsg(TClientForm *_form) : form(_form) {} void operator()() { form->LogMessage("test"); } }; typedef TMethodRef<Classes::TThreadProcedure, LogMsg, void> MyMethRef; TThread::Queue(NULL, Classes::_di_TThreadProcedure( new MyMethRef( LogMsg(this) ) ) );
仅在 Clang-based C++11 compilers 中,您可以在任何需要匿名 procedure/method 的地方使用 C++ lambda:
TThread::Queue(NULL, [this]() -> void { LogMessage("test"); } );