CïŒã®èéãéãã§ããŒãéãšãããæç¹ã§ã®Windowsã©ã³ã¿ã€ã åãã®C ++ / CXéçºã®èã¿ã«ãããWinRTããã³COMã¢ããªã±ãŒã·ã§ã³ãšã³ã³ããŒãã³ããç°¡åã«äœæã§ããWRLãã³ãã¬ãŒãã©ã€ãã©ãªã«è³ããŸããã ãã®ç¹å®ã®ã©ã€ãã©ãªãæäœãããšããã³ãŒããããèªäœã®äžã«é ãããã®ãèŠã€ããããšæããŸããã
#include "pch.h" #include "RAWinRT.WRL.h" using namespace Microsoft::WRL::Wrappers; using namespace Microsoft::WRL; using namespace ABI::RAWinRT::WRL; using namespace ABI::Windows::ApplicationModel::Background; class ABI::RAWinRT::WRL::TestTask : public RuntimeClass < RuntimeClassFlags<WinRt>, IBackgroundTask > { InspectableClass(RuntimeClass_RAWinRT_WRL_TestTask, BaseTrust); public: STDMETHODIMP Run(IBackgroundTaskInstance *taskInstance) override { return S_OK; } }; ActivatableClass(TestTask);
ãããã®äžå¯è§£ãªãã¯ãããã³ãã¬ãŒããã©ã€ãã©ãªé¢æ°ã
ãããŠãç§ã¯æãåçŽãªãã®ããå§ããããšã«ããŸããã Visual C ++ã§ããã¯ã°ã©ãŠã³ãã¿ã¹ã¯ã®åäžã®ãã¯ã©ã¹ããæã€Windowsã©ã³ã¿ã€ã ã³ã³ããŒãã³ããèšè¿°ããŸãã
ããªããããããæ¥ããã®ã«èå³ããããªããç«ãžããããã
ã³ã³ããŒãã³ããããžã§ã¯ãã®äœæãšã«ã¹ã¿ãã€ãº
æåã«ãVisual Studio 2013 IDEã§ç©ºã®ãœãªã¥ãŒã·ã§ã³ãã¡ã€ã«ãäœæããWindowsã¹ãã¢ã¢ããªã±ãŒã·ã§ã³ã®DLLãããžã§ã¯ããè¿œå ããŸããã
ãããžã§ã¯ãã§ã¯ãNMSPC.TestComponentãšããååãéžæããŸãããããã§ãNMSPCã¯åå空éã§ãã ãã®ãããªåœåã¯ããããžã§ã¯ããäœæããéã®ããªãäžè¬çãªæ
£è¡ã§ããããããã¢ç®çã§ãããè¡ããŸããã ãŸããããã©ã«ãã®ããŒã ã¹ããŒã¹ãNMSPC_TestComponentãã察å¿ãããããžã§ã¯ãåã«å€æŽããŸããã
ãã¡ã€ã«ã«ã€ããŠã¯ãçãååã奜ããããããããŒãã¡ã€ã«ãšãœãŒã¹ãã¡ã€ã«ã®ååãTetsComponentã«å€æŽããŸããã ã³ãŒãã«ã³ã³ããŒãã³ããå®è£
ããåã«ãããã€ãã®è¿œå ãã¡ã€ã«ãè¿œå ããŸããã TestComponent.def-åçã©ã€ãã©ãªã«ãã£ãŠãšã¯ã¹ããŒããããé¢æ°ãå®çŸ©ããããã®ãã¡ã€ã«ãTestComponent.idl-ã€ã³ã¿ãŒãã§ã€ã¹ãèšè¿°ããããã®ãã¡ã€ã«
ãããã®ãã¡ã€ã«ããããžã§ã¯ãã«è¿œå ããããæ§æãéå§ããŸããã åæ§æã®èšå®ãåå¥ã«å€æŽããªãããã«ããã«ã¯ããã¹ãŠã®æ§æãšãã©ãããã©ãŒã ãéžæããŠããã©ã¡ãŒã¿ãŒã®ç·šéã«é²ãã ãã§ååã§ãã ã¢ã©ãŒãã¬ãã«èšå®ãæå®ãããã¡ã¿ããŒã¿çæãªãã·ã§ã³ãæå®ãããMIDLã³ã³ãã€ã©ãŒã«ãã£ãŠçæãããããããŒãã¡ã€ã«ã®ååãã³ãã¬ãŒããå€æŽãããruntimeobject.libã®ã¬ã€ã¢ãŠããè¿œå ããããµãã·ã¹ãã ãéžæãããŸããã
次ã«ããããžã§ã¯ããæ§ç¯ããããã®è¿œå ã¹ããããèšå®ããŸããã 圌ã«ã€ããŠããå°ã説æããŸãã
ãã®ã¹ãããã¯ããããžã§ã¯ãã¡ã¿ããŒã¿ã®æ£ããçæãç®çãšããŠããŸãã ã³ãã³ãã©ã€ã³ã¯æ¬¡ã®ããã«èšå®ãããŸããã
del "$(OutDir)$(TargetName).winmd" && mdmerge -partial -i "$(OutDir)." -o "$(OutDir)Output" -metadata_dir "$(WindowsSDK_MetadataPath)" && del "$(OutDir)*.winmd" && copy /y "$(OutDir)Output\*" "$(OutDir)" && rd /q /s "$(OutDir)Output"
å°æ°ã®é£ç¶ããã¹ãããã§æ§æãããåã¹ãããã¯ç¹å®ã®ã¿ã¹ã¯ãå®è¡ããŸãã
- å®å
ãã©ã«ããŒããNMSPC.TestComponent.winmdãããžã§ã¯ãã¡ã¿ããŒã¿ãã¡ã€ã«ãåé€ããŸãã
- ã¡ã¿ããŒã¿ãã¡ã€ã«ãçµåããŸãã çµæã¯ãåºåãã©ã«ããŒã®$ïŒOutDirïŒã«é
眮ãããŸãã
- Ouputãã©ã«ããŒãã$ïŒOutDirïŒãã©ã«ããŒã«ã¡ã¿ããŒã¿ãã¡ã€ã«ãã³ããŒããŸãã
- ã³ã³ãã³ããšå
±ã«åºåãã©ã«ããŒãåé€ããŸãã
ãããã®æºåæé ããã¹ãŠå®äºããåŸãããããã³ãŒãã®èšè¿°ãéå§ã§ããŸããã
DEFãMIDLãPCH
èªå°å¿ã®ããWindowsã©ã³ã¿ã€ã ã³ã³ããŒãã³ãã©ã€ãã©ãªã¯ãã©ã³ã¿ã€ã ã«ãã£ãŠäœ¿çšããã2ã€ã®éåžžã«éèŠãªé¢æ°ãDllGetActivationFactoryããã³DllCanUnloadNowããšã¯ã¹ããŒãããå¿
èŠããããŸãã ãããã®é¢æ°ã®ãšã¯ã¹ããŒãã¯ãTestComponent.defãã¡ã€ã«ã§å®çŸ©ãããŸããïŒã³ãŒãã§å®è£
ããå¿
èŠããããŸãããããã«ã€ããŠã¯åŸã§è©³ãã説æããŸãïŒã
EXPORTS DllGetActivationFactory PRIVATE DllCanUnloadNow PRIVATE
次ã«ãTestComponent.idlãã¡ã€ã«ã§ã¯ã©ã¹ã€ã³ã¿ãŒãã§ã€ã¹ã«ã€ããŠèª¬æããŸããã
import "Windows.ApplicationModel.Background.idl"; namespace NMSPC { namespace TestComponent { [version(1.0)] [activatable(1.0)] [marshaling_behavior(agile)] [threading(both)] runtimeclass TestBackgroundTask { [default] interface Windows.ApplicationModel.Background.IBackgroundTask; }; } }
æåã®ãã£ã¬ã¯ãã£ãã¯ãWindows :: ApplicationModel :: Background :: IBackgroundTaskã®ããã¯ã°ã©ãŠã³ãã¿ã¹ã¯ã€ã³ã¿ãŒãã§ã€ã¹ã®èª¬æãå«ããã¡ã€ã«ãã€ã³ããŒãããŸãã ãã®ãã¡ã€ã«ã¯MIDLã³ã³ãã€ã©ã«ååãªã®ã§ãä»ã®ã€ã³ã¿ãŒãã§ã€ã¹èšè¿°ãã¡ã€ã«ãã€ã³ããŒãããå¿
èŠã¯ãããŸããïŒWindowsã¹ãã¢8.1ãã©ãããã©ãŒã ã®å Žåãã€ã³ã¿ãŒãã§ã€ã¹èšè¿°ãã¡ã€ã«ãšããããŒãã¡ã€ã«ã¯CïŒ\ Program FilesïŒx86ïŒ\ Windows Kits \ 8.1 \ Include \ winrtã«ãããŸãïŒ ã ã¯ã©ã¹ã®åå空éã¯ããããžã§ã¯ãåNMSPC :: TestComponentã«åŸã£ãŠéžæãããŸããã å±æ§ã䜿çšããŠãã¯ã©ã¹ã®ããŒãžã§ã³ïŒããŒãžã§ã³ïŒãããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ãŒã®ååšã®å
åïŒèµ·åå¯èœïŒãã¹ã¬ããã®æäœïŒã¹ã¬ããåïŒããã³ããŒã·ã£ãªã³ã°ïŒmarshaling_behaviorïŒãèšå®ããŸããã MIDLã³ã³ãã€ã©ã䜿çšããŠãããã³ã³ãã€ã«ãããšãTetsComponent.hããããŒãã¡ã€ã«ãååŸãããŸããã
ã³ã³ãã€ã«æéãççž®ãããããpch.hãã¡ã€ã«ïŒããªã³ã³ãã€ã«æžã¿ããããŒãã¡ã€ã«ã®çæã«äœ¿çšïŒã«activation.hããã³æ°ããããããŒãã¡ã€ã«ãå«ããããã®ãã£ã¬ã¯ãã£ããè¿œå ã§çºè¡ããŸããã ãããã®ããããŒãã¡ã€ã«ãå«ããå¿
èŠãããããšã¯ãIActivationFactoryã€ã³ã¿ãŒãã§ã€ã¹ã®äŸåé¢ä¿ãšstd :: nothrowå®æ°ã«ãã£ãŠèª¬æãããŠããŸãã
#pragma once #include "targetver.h" #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
ã³ãŒãã«ã¯ã©ã¹ããã¡ã¯ããªããšã¯ã¹ããŒããããé¢æ°ãå®è£
ããããã«æ®ã£ãã ãã§ãã
ã³ãŒã
ãŸããããªã³ã³ãã€ã«æžã¿ããããŒãã¡ã€ã«ã«å ããŠãMIDLã³ã³ãã€ã©ãŒã«ãã£ãŠçæãããTestComponent.hããããŒãã¡ã€ã«ãTestComponent.cppã³ãŒããã¡ã€ã«ã«å«ããŸããã æ
£äŸã«ãããã³ã³ãã€ã©çšã«MIDLã«ãã£ãŠçæããããã¹ãŠã®ã€ã³ã¿ãŒãã§ã€ã¹ã¯ABIåå空éã«é
眮ããããããã¯ã©ã¹ãšãã®å®£èšã®ã€ã³ã¿ãŒãã§ã€ã¹ã¯ABI :: NMSPC :: TestComponentã«é
眮ãããããã¯ã°ã©ãŠã³ãã¿ã¹ã¯ãABI :: Windows :: ApplicationModel :: BackgroundïŒåå空éå
šäœãã€ã³ããŒãããã®ã§ã¯ãªããåã
ã®ã€ã³ã¿ãŒãã§ã€ã¹ã®ã¿ã®äœ¿çšã瀺ããŸããïŒã
#include "pch.h" #include "TestComponent.h"
ããã¯ã°ã©ãŠã³ãã¿ã¹ã¯ã®å®è£
ã¯ã©ã¹ã¯éåžžã«ã·ã³ãã«ã§ããããšãå€æããŸããã æ¬è³ªçã«ãIUnknownãIInspectableãããã³IBackgroundTaskã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ããå¿
èŠããããŸããã
ã¯ã©ã¹ã®æºåãã§ããã®ã§ããªããžã§ã¯ããã¡ã¯ããªã¯ã©ã¹ãäœæããå¿
èŠããããŸããã ãã®ãã¡ã¯ããªã¯ã©ã¹ã¯ãactivation.hããããŒãã¡ã€ã«ã§å®çŸ©ãããŠããIActivationFactoryã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ããå¿
èŠããããŸãã ãã®ã€ã³ã¿ãŒãã§ã€ã¹ã¯ãIInspectableïŒãããã£ãŠIUnknownïŒãç¶æ¿ããããšã«å ããŠãã¡ãœãããå®çŸ©ããŸã
virtual HRESULT STDMETHODCALLTYPE ActivateInstance( __RPC__deref_out_opt IInspectable **instance) = 0;
MSDNã®ã¡ãœããã®ããã¥ã¡ã³ãã§èª¬æãããŠããããã«ãGetRuntimeClassNameã¡ãœããã®å®è£
ãç°ãªãå¿
èŠããããŸãã
https://msdn.microsoft.com/en-us/library/br205823(v=vs.85).aspx
泚ææ·±ãèªè
ã¯ãã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ãšãã¹ãã©ã¯ã¿ã®å¥åŠãªè©³çŽ°ãã€ãŸãå€æ°m_objectsCountã®ã€ã³ã¯ãªã¡ã³ããšãã¯ãªã¡ã³ãã«æ°ä»ãã§ãããã ã¯ã©ã¹ã³ãŒãã®åã«ãã£ã¬ã¯ãã£ãã䜿çšããçŽåŸã«ããã®å€æ°ã宣èšããŸããã ãããŠãDllCanUnloadNowé¢æ°ã®ãšã¯ã¹ããŒããããã©ã€ãã©ãªã§äœ¿çšãããŸãã
ãã®é¢æ°ã«å ããŠãå¥ã®DllGetActivationFactoryãå®çŸ©ãããŸãããããã¯ãã¯ã©ã¹èå¥åïŒWindowsã©ã³ã¿ã€ã ã§ã¯ãã¹ãŠã®åå空éãå«ãæååïŒã§ãã¡ã¯ããªãåãåãããšãç®çãšããŠããŸãã
CïŒã¢ããªã±ãŒã·ã§ã³ã§ã®ã³ã³ããŒãã³ãã®äœ¿çšã«ã€ããŠèª¬æããåã«ãdllmain.cppãã¡ã€ã«ã§å®çŸ©ãããŠããDllMainé¢æ°ã®æ瀺çãªå®è£
ã«ã€ããŠã説æããŸãã 蚺æç®çã§ã®ã¿äœ¿çšããŸãããããŠãŒã¹ã±ãŒã¹ã¯ç§ã®ãã®ãšã¯ç°ãªãå ŽåããããŸãã
#include "pch.h" BOOL APIENTRY DllMain(HMODULE , DWORD ul_reason_for_call, LPVOID ) { OutputDebugStringW(L"Hello from DLL.\r\n"); return TRUE; }
ããã§ãã³ã³ããŒãã³ãã©ã€ãã©ãªã®å®è£
ãå®äºããŸããã ãããŠãã¢ããªã±ãŒã·ã§ã³ã§ã®å®çšåãéå§ããããšãã§ããŸããã
CïŒã¢ããªã±ãŒã·ã§ã³
Blank Appãã³ãã¬ãŒãã䜿çšããŠNMSPC.CSTestApppã¢ããªã±ãŒã·ã§ã³ãããžã§ã¯ããäœæããããã³ã³ããŒãã³ããããžã§ã¯ããšMicrosoft Visual C ++ 2013ã©ã³ã¿ã€ã ããã±ãŒãžãžã®ãªã³ã¯ãè¿œå ããŸããã
æ®ã£ãã®ã¯ãã¢ããªã±ãŒã·ã§ã³ãããã§ã¹ããã¡ã€ã«ãç·šéããŠãããã¯ã°ã©ãŠã³ãã¿ã¹ã¯ã®å®çŸ©ãè¿œå ããããã¯ã°ã©ãŠã³ãã¿ã¹ã¯ãç»é²ããã³ãŒããæžãããšã ãã§ããã
ã³ãŒãã¯ãAppã¯ã©ã¹ã®OnLaunchedã¡ãœããã«é
眮ãããŸãã ã³ãŒãã¯åçŽã§ããæåã«ãã¹ãŠã®ã¿ã¹ã¯ç»é²ãåé€ããŠãããã¿ã¹ã¯ãã«ããªããžã§ã¯ããäœæãããããã§ã¹ãã§æå®ãããããªã¬ãŒãèšå®ããŠãã¿ã¹ã¯ãç»é²ããŸãã
foreach (var pair in BackgroundTaskRegistration.AllTasks) { pair.Value.Unregister(true); } var taskBuilder = new BackgroundTaskBuilder { Name = "TestBackgroundTask", TaskEntryPoint = "NMSPC.TestComponent.TestBackgroundTask" }; taskBuilder.SetTrigger(new SystemTrigger(SystemTriggerType.TimeZoneChange, true)); taskBuilder.Register();
C ++ã³ãŒãã®ãã¬ãŒã¯ãã€ã³ãã«ç§»åã§ããããã«ããããã«ãã¢ããªã±ãŒã·ã§ã³ãããžã§ã¯ãã®ãããã°èšå®ã§ããã»ã¹ã¿ã€ãMixedïŒManaged and NativeïŒãèšå®ããŸãã ãšããã§ããã®èšå®ã¯C ++ / CXã¢ããªã±ãŒã·ã§ã³ã«ãé¢é£ããŠããŸãã
ããã§ããããã°ã¢ãŒãã§ã¢ããªã±ãŒã·ã§ã³ãèµ·åããã³ã³ããŒãã³ãç»é²ã³ãŒããå®è¡ãã[ãããã°ã®å Žæ]ã»ã¯ã·ã§ã³ã®[ã©ã€ããµã€ã¯ã«ã€ãã³ã]ãã¿ã³ã䜿çšããŠããã¯ã°ã©ãŠã³ãã¿ã¹ã¯ã®èµ·åããã¹ãã§ããŸããã
ãããå®è¡ãããšãåºåãŠã£ã³ããŠã«éåžžã«å€§äºãªè¡ã衚瀺ããããã®åºåã¯OutputDebugStringWé¢æ°ã䜿çšããŠC ++ã³ãŒãã§ããã°ã©ã ãããŸããã
Hello from DLL. Hello from background task.
ãããã«
çµå±ã®ãšãããWRLã䜿çšããã«ã³ã³ããŒãã³ãã³ãŒããèšè¿°ããããšãå¯èœã§ãã ãã®åé¡ã®è§£æ±ºçã«ãããWindowsã©ã³ã¿ã€ã ç°å¢ã®ã³ã³ããŒãã³ãéã®çžäºäœçšã®å®è¡ã¡ã«ããºã ãšåçãããããç解ããããšãå¯èœã«ãªããŸããã
GitHubã§å
¥æå¯èœãªãœãŒã¹ã³ãŒã
https://github.com/altk/RuntimeComponent