Featured post
delphi - Do C++ Templates play nicely with VCL classes? -
i'm trying use c++ template 'mixins' create new vcl components shared additional functionality. example...
template <class t> class mixin : public t { private: typedef t inherited; // ...additional methods public: mixin(tcomponent *owner) : inherited(owner) { // .. stuff here }; };
used this:
class mylabel : public mixin<tlabel> { .... } class myedit : public mixin<tedit> { .... }
now, compiles fine, , mixin stuff seems work - until try , save component stream using tstream->writecomponent, inherited properties (eg tlabel.width/height/etc.) don't written. 'null' mixin 1 shown above.
my code works fine when deriving classes directly tform, tedit, etc - , class correctly registered streaming system.
the quick/simple answer is: no; when dealing template, compiler won't generate proper descriptors make streaming working. however, since has come before, peeked under cover find out what's missing. , found it's there. here's little more information.
upfront compiler never treat template-based type delphi. example, this:
void testing() { __classid(mixin<stdctrls::tlabel>); // error here }
... , you'll see error
"error e2242 test.cpp 53: __classid requires delphi style class type (i.e. class marked __declspec(delphiclass) or derived system::tobject) in function testing()"
this says compiler not consider type/class compatible delphi-classes [i.e. derive tobject]. internally there's flag on symbol says whether type delphi-compatible or not. , noticed trick compiler marking type delphi-style if forced walk hierarchy.. has if create instance of object. so, hack error goes away:
void testing() { typedef mixin<stdctrls::tlabel> __ttype; std::auto_ptr<__ttype> c2(new __ttype(0)); __classid(mixin<stdctrls::tlabel>); // no more errors here }
but nicer use __declspec(delphiclass) directly on template, in:
template <class t> class __declspec(delphiclass) mixin : public t { private: int i; typedef t inherited; public: __fastcall mixin(tcomponent *owner) : inherited(owner) {}; };
so compiler treats type delphi-style class without hacks, peeked little more , found issue you're running into: delphi classes have ttypedata.propcount field - http://docwiki.embarcadero.com/vcl/en/typinfo.ttypedata - sum of class' properties, including of base classes. due way various pieces of information computed, compiler writes out '0' field when template involved:(
you can see printing out propcount, in:
#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))); (int = 0; < 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; }
when run above prints:
class: tcppcomp - total props:3 aaaa name tag class: @%mixin$8tcppcomp% - total props:0
iow, mixin shows '0' published properties while base type has 3:(
i suspect streaming system relies on count , that's why inherited properties not being written out in setup.
i considered tweaking generated descriptors @ runtime since write them _text it's bound trigger dep.
i'll @ logic computes propcount see if there's way compute correct number. if time allows, please open qc this: i've peek underneath, believe not require effort working expected.
cheers,
bruneau
ps: in sample had mixin publish property , compiler generated correct descriptor property; however, total count still zero.
- Get link
- X
- Other Apps
Comments
Post a Comment