您的位置:首页 > 编程语言 > C语言/C++

Connecting C++ and XAML

2015-10-07 19:07 555 查看


TheBuildProcess

Fromauser-facingstandpoint,Pagesandothercustomcontrolsarereallyatrioofuser-editablefiles. Forexample,thedefinitionoftheclassMainPageiscomprisedofthreefiles:MainPage.xaml,
MainPage.xaml.h,andMainPage.xaml.cpp. Bothmainpage.xamlandmainpage.xaml.hcontributetotheactualdefinitionoftheMainPageclass,whileMainPage.xaml.cppprovidesthemethodimplementationsforthosemethodsdefinedinMainPage.xaml.h. However,how
thisactuallyworksinpracticeisfarmorecomplex.

 



Thisdrawingisverycomplex,sopleasebearwithmewhileIbreakitdownintoitsconstituentpieces.

Everyboxinthediagramrepresentsafile. Thelight-bluefilesontheleftsideofthediagramarethefileswhichtheuseredits. ThesearetheonlyfilesthattypicallyshowupintheSolution
Explorer. I’llspeakspecificallyaboutMainPage.xamlanditsassociatedfiles,butthissameprocessoccursfo
4000
rallxaml/h/cpptriosintheproject.

ThefirststepinthebuildisXAMLcompilation,whichwillactuallyoccurinseveralsteps. First,theuser-editedMainPage.xamlfileisprocessedtogenerateMainPage.g.h. Thisfileisspecial
inthatitisprocessedatdesign-time(thatis,youdonotneedtoinvokeabuildinordertohavethisfilebeupdated). ThereasonforthisisthateditsyoumaketoMainPage.xamlcanchangethecontentsoftheMainPageclass,andyouwantthosechanges
tobereflectedinyourIntellisensewithoutrequiringarebuild. Exceptforthisstep,alloftheotherstepsonlyoccurwhenauserinvokesaBuild.


PartialClasses

Youmaynotethatthebuildprocessintroducesaproblem:theclassMainPageactuallyhastwodefinitions,onethatcomesfromMainPage.g.h:
partialrefclassMainPage:public::Windows::UI::Xaml::Controls::Page,
      public::Windows::UI::Xaml::Markup::IComponentConnector
{
public:
  voidInitializeComponent();
  virtualvoidConnect(intconnectionId,::Platform::Object^target);

private:
  bool_contentLoaded;

};


AndonethatcomesfromMainPage.xaml.h:
publicrefclassMainPagesealed
{
public:
  MainPage();

protected:
  virtualvoidOnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^e)override;
};


Thisissueisreconciledviaanewlanguageextension:PartialClasses.

Thecompilerparsingofpartialclassesisactuallyfairlystraightforward. First,allpartialdefinitionsforaclassmustbewithinonetranslationunit. Second,allclassdefinitionsmustbemarked
withthekeyword partial exceptfortheverylastdefinition(sometimesreferredtoasthe‘final’definition). Duringparsing,thepartialdefinitionsaredeferredbythecompileruntil
thefinaldefinitionisseen,atwhichpointallofthepartialdefinitions(alongwiththefinaldefinition)arecombinedtogetherandparsedasonedefinition. ThisfeatureiswhatenablesboththeXAML-compiler-generatedfileMainPage.g.handtheuser-editable
fileMainPage.xaml.htocontributetothedefinitionoftheMainPageclass.


Compilation

Forcompilation,MainPage.g.hisincludedinMainPage.xaml.h,whichisfurtherincludedinMainPage.xaml.cpp. ThesefilesarecompiledbytheC++compilertoproduceMainPage.obj. (Thiscompilation
isrepresentedbytheredlinesintheabovediagram.) MainPage.obj,alongwiththeotherobjfilesthatareavailableatthisstagearepassedthroughthelinkerwiththeswitch/WINMD:ONLYtogeneratetheWindowsMetadata(WinMD)filefortheproject.This
processisdenotedinthediagrambytheorangeline. Atthisstagewearenotlinkingthefinalexecutable,onlyproducingtheWinMDfile,becauseMainPage.objstillcontainssomeunresolvedexternalsfortheMainPageclass,namelyanyfunctionswhichare
definedinMainPage.g.h(typicallytheInitializeComponentandConnectfunctions). ThesedefinitionsweregeneratedbytheXAMLcompilerandplacedintoMainPage.g.hpp,whichwillbecompiledatalaterstage.

MainPage.g.hpp,alongwiththe*.g.hppfilesfortheotherXAMLfilesintheproject,willbeincludedinafilecalledXamlTypeInfo.g.cpp. Thisisforbuildperformanceoptimization:thesevarious
.hppfilesdonotneedtobecompiledseparatelybutcanbebuiltasonetranslationunitalongwithXamlTypeInfo.g.cpp,reducingthenumberofcompilerinvocationsrequiredtobuildtheproject.


DataBindingandXamlTypeInfo

DatabindingisakeyfeatureofXAMLarchitecture,andenablesadvanceddesignpatternssuchasMVVM. C++fullysupportsdatabinding;however,inorderfortheXAMLarchitecturetoperformdata
binding,itneedstobeabletotakethestringrepresentationofafield(suchas“FullName”)andturnthatintoapropertygettercallagainstanobject. Inthemanagedworld,thiscanbeaccomplishedwithreflection,butnativeC++doesnothaveabuilt-in
reflectionmodel.

Instead,theXAMLcompiler(whichisitselfa.NETapplication)loadstheWinMDfilefortheproject,reflectsuponit,andgeneratesC++sourcethatendsupintheXamlTypeInfo.g.cppfile. It
willgeneratethenecessarydatabindingsourceforanypublicclassmarkedwiththeBindableattribute.

Itmaybeinstructivetolookatthedefinitionofadata-bindableclassandseewhatsourceisgeneratedthatenablesthedatabindingtosucceed. Hereisasimplebindableclassdefinition:
[Windows::UI::Xaml::Data::Bindable]
publicrefclassSampleBindableClasssealed{
public:
  propertyPlatform::String^FullName;
};


Whenthisiscompiled,astheclassdefinitionispublic,itwillendupintheWinMDfileasseenhere:





ThisWinMDisprocessedbytheXAMLcompilerandaddssourcetotwoimportantfunctionswithinXamlTypeInfo.g.cpp: CreateXamlType and CreateXamlMember .

Thesourceaddedto CreateXamlType generatesbasictypeinformationfortheSampleBindableClass type,
providesanActivator(afunctionthatcancreateaninstanceoftheclass)andenumeratesthemembersoftheclass:
if(typeName==L"BlogDemoApp.SampleBindableClass")
{
 XamlUserType^userType=refnewXamlUserType(this,typeName,GetXamlTypeByName(L"Object"));
 userType->KindOfType=::Windows::UI::Xaml::Interop::TypeKind::Custom;
 userType->Activator= 
  []()->Platform::Object^
  {
    returnrefnew::BlogDemoApp::SampleBindableClass();
  };
 userType->AddMemberName(L"FullName");
 userType->SetIsBindable();
 returnuserType;
}


Notehowalambdaisusedtoadaptthecallto refnew (whichwillreturnaSampleBindableClass^ )
intothe Activator function(whichalwaysreturnsan Object^ ).


FromStringtoFunctionCall

AsImentionedpreviously,thefundamentalissuewithdatabindingistransformingthetextnameofaproperty(inourexample,“FullName”)intothegetterandsetterfunctioncallsforthisproperty. 
Thistranslationmagicisimplementedbythe XamlMember class.

XamlMember storestwofunctionpointers: Getter and Setter . Thesefunction
pointersaredefinedagainstthebasetype Object^ (whichallWinRTandfundamentaltypescanconvertto/from). A XamlUserType stores
a map<String^,XamlUserType^> ;whendatabindingrequiresagetterorsettertobecalled,theappropriate XamlUserType canbe
foundinthemapanditsassociated Getter or Setter functionpointercanbeinvoked.

Thesourceaddedto CreateXamlMember initializesthese Getter and Setter function
pointersforeachproperty. ThesefunctionpointersalwayshaveaparameteroftypeObject^ (theinstanceoftheclasstogetfromorsetto)andeitherareturnparameteroftypeObject^ (in
thecaseofagetter)orhaveasecondparameteroftype Object^ (forsetters).

if(longMemberName==L"BlogDemoApp.SampleBindableClass.FullName")
{
 XamlMember^xamlMember=refnewXamlMember(this,L"FullName",L"String");
 xamlMember->Getter=
 [](Object^instance)->Object^
 {
   autothat=(::BlogDemoApp::SampleBindableClass^)instance;
   returnthat->FullName;
 };

 xamlMember->Setter=
 [](Object^instance,Object^value)->void
 {
   autothat=(::BlogDemoApp::SampleBindableClass^)instance;
   that->FullName=(::Platform::String^)value;
 };
 returnxamlMember;
}


Thetwolambdasdefinedusethelambda‘decaytopointer’functionalitytobindto Getterand Setter methods. 
Thesefunctionpointerscanthenbecalledbythedatabindinginfrastructure,passinginanobjectinstance,inordertosetorgetapropertybasedononlyitsname. Withinthelambdas,thegeneratedcodeaddsthepropertypecastsinordertomarshalto/from
theactualtypes.


FinalLinkingandFinalThoughts

Aftercompilingthexamltypeinfo.g.cppfileintoxamltypeinfo.g.obj,wecanthenlinkthisobjectfilealongwiththeotherobjectfilestogeneratethefinalexecutablefortheprogram. This
executable,alongwiththewinmdfilepreviouslygenerated,andyourxamlfiles,arepackagedupintotheapppackagethatmakesupyourWindowsStoreApplication.

Anote:theBindableattributedescribedinthispostisonewaytoenabledatabindinginWinRT,butitisnottheonlyway. Databindingcanalsobeenabledonaclassbyimplementingeither
theICustomPropertyProviderinterfaceorIMap<String^,Object^>. TheseotherimplementationswouldbeusefuliftheBindableattributecannotbeused,particularlyifyouwantanon-publicclasstobedata-bindable.

Foradditionalinfo,Irecommendlookingat this
walkthrough ,whichwillguideyouthroughbuildingafully-featuredWindowsStoreApplicationinC++/XAMLfromthegroundup. TheMicrosoftPatternsandPracticesteamhasalsodeveloped
alargeapplicationwhichdemonstratessomebestpracticeswhendevelopingWindowsStoreApplicationsinC++:projectHilo. Thesourcesanddocumentationforthisprojectcanbefoundathttp://hilo.codeplex.com/ . 
(NotethatthisprojectmaynotyetbeupdatedfortheRTMreleaseofVisualStudio.)

Ihopethisposthasgivenyousomeinsightintohowuser-editedfilesandgeneratedfilesarecompiledtogethertoproduceafunctional(andvalid)C++program,andgivenyousomeinsightinto
howtheXAMLdatabindinginfrastructureactuallyworksbehindthescenes.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: