快速/简单的答案是:不;在处理模板时,编译器不会生成正确的描述符来使流式传输工作。但是,由于以前出现过这种情况,因此我在封面下偷看以找出缺少的内容。我发现它几乎就在那里。所以这里有更多信息。
预先编译器永远不会将基于模板的类型视为 Delphi。例如,执行以下操作:
void testing()
{
__classid(Mixin<Stdctrls::TLabel>); // Error Here
}
...你会看到错误
"错误 E2242 test.cpp 53: __classid 在函数 testing() 中需要 Delphi 样式的类类型(即标记为 __declspec(delphiclass) 或派生自 System::TObject 的类)"
这基本上是说编译器不认为这个类型/类与 Delphi 类兼容 [即那些从 TObject 派生的]。在内部,符号上只有一个标志,表示该类型是否与 delphi 兼容。而且我注意到,如果我强迫编译器向上走层次结构,我可以欺骗编译器将类型标记为 delphi 样式。如果我创建对象的实例,这是它必须做的事情。因此,有了这个 hack,错误就消失了:
void testing()
{
typedef Mixin<Stdctrls::TLabel> __ttype;
std::auto_ptr<__ttype> c2(new __ttype(0));
__classid(Mixin<Stdctrls::TLabel>); // No more errors here
}
但实际上更好的是直接在模板上使用 __declspec(delphiclass),如下所示:
template <class T>
class __declspec(delphiclass) Mixin : public T {
private:
int i;
typedef T inherited;
public:
__fastcall Mixin(TComponent *owner) : inherited(owner) {};
};
既然编译器将类型视为没有 hack 的 delphi 样式类,我又看了看,发现您可能遇到的问题:Delphi 类有 TTypeData.PropCount 字段 - http://docwiki.embarcadero.com/VCL/en/TypInfo.TTypeData -是类属性的总和,包括其基类的属性。由于计算各种信息的方式,当涉及模板时,编译器会为该字段写出“0”:(
您可以通过打印出 PropCount 来查看这一点,如下所示:
#include <Stdctrls.hpp>
#include <cstdio>
#include <memory>
#include <utilcls.h>
class TCppComp : public Classes::TComponent {
int i;
public:
__fastcall TCppComp(TComponent* owner): Classes::TComponent(owner) {};
__published:
__property int AAAA = {read=i, write=i};
};
template <class T>
class __declspec(delphiclass) Mixin : public T {
private:
int i;
typedef T inherited;
public:
__fastcall Mixin(TComponent *owner) : inherited(owner) {};
};
typedef Mixin<TCppComp> TMixinComp;
void showProps(TClass meta) {
PTypeInfo pInfo = PTypeInfo(meta->ClassInfo());
int Count = GetPropList(pInfo, tkAny, NULL);
TAPtr<PPropInfo> List(new PPropInfo[Count]);
std::printf("Class: %s - Total Props:%d\n",
AnsiString(pInfo->Name).c_str(), Count);
GetPropList(pInfo, tkAny, *(reinterpret_cast<PPropList*>(&List)));
for (int i = 0; i < Count; i++) {
AnsiString propName(List[i]->Name);
std::printf("\t%s\n", propName.c_str());
}
}
void test() {
showProps(__classid(TCppComp));
showProps(__classid(TMixinComp));
}
int main() {
test();
return 0;
}
运行上述打印时:
Class: TCppComp - Total Props:3
AAAA
Name
Tag
Class: @%Mixin$8TCppComp% - Total Props:0
IOW,Mixin 显示为 '0' 已发布属性,而其基本类型为 3:(
我怀疑流系统依赖于这个计数,这就是为什么没有在你的设置中写出继承的属性。
我考虑在运行时调整生成的描述符,但由于我们将它们写入 _TEXT,它必然会触发 DEP。
我将查看计算 PropCount 的逻辑,看看是否有某种方法可以让它计算出正确的数字。如果时间允许,请为此打开一个 QC:现在我已经窥视了下面的内容,我相信它不需要太多努力就可以按预期工作。
干杯,
布鲁诺
PS:在我的示例中,我什至让 Mixin 发布了一个属性,编译器为该属性生成了正确的描述符;但是,总数仍然为零。