You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ Builder 12中使用RTTI创建TValue<TNotifyEvent>时类型转换异常问题

解决RTTI赋值TNotifyEvent事件属性的类型转换异常问题

问题原因

TNotifyEvent是闭包函数指针void (__closure *)(TObject*)的typedef别名。用TValue::From<TNotifyEvent>生成TValue时,RTTI关联的是底层函数指针的类型信息,而非TNotifyEvent这个typedef的类型信息。但事件属性的RTTI类型是TNotifyEvent,导致SetValue时因类型不匹配触发EInvalidCast异常。

直接赋值btn->OnClick = &closeBtnClick;能正常工作,是因为编译期编译器会自动处理typedef别名的类型匹配;而RTTI是运行期机制,要求类型信息严格一致。

解决方案

通过TValue::Make方法手动指定TNotifyEvent的类型信息,让TValue关联正确的RTTI类型:

方法1:直接生成正确的TValue

修改调用代码:

// 先创建TNotifyEvent类型的 handler
TNotifyEvent handler = &closeBtnClick;
// 用Make方法指定TNotifyEvent的TypeInfo生成TValue
auto value = TValue::Make(&handler, __typeinfo(TNotifyEvent));
setProperty(btn, "OnClick", value);

方法2:基于TMethod的正确实现

如果需要通过RTTI获取方法地址,修正后的代码如下:

auto* context = getContext();
auto* method = context->GetType(__classid(TStandardPanel))->GetMethod("closeBtnClick");
TMethod tm;
tm.Code = method->CodeAddress;
tm.Data = this;
// 将TMethod转换为TNotifyEvent,再用Make指定类型信息
TNotifyEvent handler = reinterpret_cast<TNotifyEvent>(tm);
auto value = TValue::Make(&handler, __typeinfo(TNotifyEvent));
setProperty(btn, "OnClick", value);

验证说明

修改后,value.TypeInfo->Name会显示为TNotifyEvent,与事件属性的类型信息完全匹配,调用SetValue时就不会触发类型转换异常了。

内容的提问来源于stack exchange,提问作者Ингибитор Палладиум

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 16:03:21