[英]FMX System messaging to send a pointer(?)
I'm using C++Builder 10.2.我正在使用 C++Builder 10.2。
In Android, I would like to send messages from various threads, including the main thread, to the main GUI thread.在Android中,我想从各种线程(包括主线程)向主GUI线程发送消息。 In Windows, I could post a message and assign an LPARAM or WPARAM to the address of some instance of a struct or class.
在 Windows 中,我可以发布一条消息并将 LPARAM 或 WPARAM 分配给结构或类的某个实例的地址。
I'm trying to use System.Messaging.TMessageManager
to do the same thing, similar to the example here: System.Messaging (C++) .我正在尝试使用
System.Messaging.TMessageManager
来做同样的事情,类似于这里的示例: System.Messaging (C++) 。 But I can only send 'simple' types, like UnicodeString
or int
.但我只能发送“简单”类型,如
UnicodeString
或int
。 I haven't worked out how to send a pointer, assuming it's even possible at all.我还没有弄清楚如何发送一个指针,假设它甚至是可能的。
I would like to send a struct/class instance like this:我想发送这样的结构/类实例:
class TSendResult
{
public:
String Message;
unsigned int Value;
int Errno;
__fastcall TSendResult(void);
__fastcall ~TSendResult();
};
If this can be done, how do I write this?如果这可以做到,我该怎么写? I managed to get one version to compile, but got a linker error:
我设法编译了一个版本,但出现链接器错误:
error: undefined reference to 'vtable for System::Messaging::TMessage__1<TSendResult>'
错误:未定义对“System::Messaging::TMessage__1<TSendResult>”的引用
Form constructor:表单构造函数:
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
TMessageManager* MessageManager = TMessageManager::DefaultManager;
TMetaClass* MessageClass = __classid(TMessage__1<TSendResult>);
TMessageListenerMethod ShowReceivedMessagePointer = &(this->MMReceiveAndCallBack);
MessageManager->SubscribeToMessage(MessageClass, ShowReceivedMessagePointer);
}
Button click handler:按钮点击处理程序:
void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
{
...
TSendResult *SPtr = new TSendResult();
SPtr->Message = "All good";
SPtr->Value = 10;
SPtr->Errno = 0;
TMessageManager* MessageManager = TMessageManager::DefaultManager;
TMessage__1<TSendResult>* Message = new TMessage__1<TSendResult>(*SPtr); // <-- this doesn't look right...
MessageManager->SendMessage(Sender, Message, false);
}
Function that captures messages:捕获消息的函数:
void __fastcall TForm1::MMReceiveAndCallBack(System::TObject* const Sender,
System::Messaging::TMessageBase* const M)
{
TMessage__1<TSendResult>* Message = dynamic_cast<TMessage__1<TSendResult>*>(M);
if (Message) {
ShowMessage(Message->Value.Message);
}
}
TMessage__1<T>
is a C++ class implementation for the Delphi Generic TMessage<T>
class. TMessage__1<T>
是 Delphi Generic TMessage<T>
类的 C++ 类实现。 Unfortunately, there is a documented limitation when using Delphi Generic classes in C++, which is why you are getting a linker error:不幸的是,在 C++ 中使用 Delphi 泛型类时有一个记录限制,这就是为什么您会收到链接器错误的原因:
How to Handle Delphi Generics in C++ 如何在 C++ 中处理 Delphi 泛型
Delphi generics are exposed to C++ as templates.
Delphi 泛型作为模板暴露给 C++。 However, it is important to realize that the instantiations occur on the Delphi side, not in C++.
然而,重要的是要意识到实例化发生在 Delphi 端,而不是在 C++ 中。 Therefore, you can only use these template for types that were explicitly instantiated in Delphi code .
因此,您只能将这些模板用于在 Delphi 代码中显式实例化的类型。
...
...
If C++ code attempts to use a Delphi generic for types that were not instantiated in Delphi, you'll get errors at link time.
如果 C++ 代码尝试对未在 Delphi 中实例化的类型使用 Delphi 泛型,则会在链接时收到错误。
Which is why TMessage__1<UnicodeString>
works but TMessage__1<TSendResult>
does not, as there is an instantiation of TMessage<UnicodeString>
present in the Delphi RTL.这就是为什么
TMessage__1<UnicodeString>
有效但TMessage__1<TSendResult>
无效的原因,因为 Delphi RTL 中存在TMessage<UnicodeString>
的实例化。 Whoever wrote the C++ example you are looking at was likely not aware of this limitation and was just translating the Delphi example as-is.编写您正在查看的C++ 示例的人可能没有意识到这一限制,只是按原样翻译了Delphi 示例。
That being said, you have two choices:话虽如此,你有两个选择:
.pas
unit to your C++ project, implementing TSendResult
as a Delphi record
, and defining an instantiation of TMessage<TSendResult>
for it..pas
单元添加到您的 C++ 项目,将TSendResult
实现为 Delphi record
,并TMessage<TSendResult>
定义TMessage<TSendResult>
的实例化。 Then you can use that unit in your C++ code (C++Builder will generate a C++ .hpp
file for you when the .pas
file is compiled), eg:.hpp
为您的文件时.pas
文件编译),例如:unit MyMessageTypes;
interface
uses
System.Messaging;
type
TSendResult = record
Message: String;
Value: UInt32;
Errno: Integer;
end;
TSendResultMsg = TMessage<TSendResult>;
implementation
initialization
TSendResultMsg.Create.Free;
finalization
end.
#include "MyMessageTypes.hpp"
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
TMessageManager::DefaultManager->SubscribeToMessage(__classid(TSendResultMsg), &MMReceiveAndCallBack);
}
void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
{
...
TSendResult Res;
Res.Message = _D("All good");
Res.Value = 10;
Res.Errno = 0;
TSendResultMsg *Message = new TSendResultMsg(Res);
TMessageManager::DefaultManager->SendMessage(this, Message, true);
}
void __fastcall TForm1::MMReceiveAndCallBack(System::TObject* const Sender,
System::Messaging::TMessageBase* const M)
{
const TSendResultMsg* Message = static_cast<const TSendResultMsg*>(M);
ShowMessage(Message->Value.Message);
}
TMessage__1
at all, you can instead derive TSendResult
directly from TMessageBase
, eg:TMessage__1
可言,可以改为派生TSendResult
直接从TMessageBase
,如:class TSendResultMsg : public TMessageBase
{
public:
String Message;
unsigned int Value;
int Errno;
};
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
TMessageManager::DefaultManager->SubscribeToMessage(__classid(TSendResultMsg), &MMReceiveAndCallBack);
}
void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
{
...
TSendResultMsg *Message = new TSendResultMsg;
Message->Message = _D("All good");
Message->Value = 10;
Message->Errno = 0;
TMessageManager::DefaultManager->SendMessage(this, Message, true);
}
void __fastcall TForm1::MMReceiveAndCallBack(System::TObject* const Sender,
System::Messaging::TMessageBase* const M)
{
const TSendResultMsg* Message = static_cast<const TSendResultMsg*>(M);
ShowMessage(Message->Message);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.