{"id":104462,"date":"2020-11-19T07:00:00","date_gmt":"2020-11-19T15:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=104462"},"modified":"2020-11-19T06:18:44","modified_gmt":"2020-11-19T14:18:44","slug":"20201119-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20201119-00\/?p=104462","title":{"rendered":"Other uses for the -library flag of the C++\/WinRT compiler"},"content":{"rendered":"<p>Last time, we saw that you can add the <code>-library<\/code> flag to the <code>cppwinrt.exe<\/code> command line if you intend to <a title=\"On combining static libraries that implement C++\/WinRT activatable objects\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20201118-00\/?p=104459\"> combine static libraries into a single C++\/WinRT module<\/a>.<\/p>\n<p>But the flag can be used even if there are no static libraries involved.<\/p>\n<p>Once you use the flag to become in charge of implementing <code>winrt_<\/code><code>get_<\/code><code>activation_<\/code><code>factory<\/code> and <code>winrt_<\/code><code>can_<\/code><code>unload_<\/code><code>now<\/code>, you can add other bonus code to the functions to add custom behavior.<\/p>\n<p>If we use the enigmatic name <code>-library I<\/code>, then the original version will be prefixed with <code>I<\/code>, which is a bit of an English grammar hack, like the Visual Basic language keywords <code>Me<\/code> and <code>My<\/code>.<\/p>\n<pre>bool __stdcall winrt_can_unload_now() noexcept\r\n{\r\n  bool unload = I_can_unload_now();\r\n  if (unload) {\r\n    FlushLoggingBuffers();\r\n  }\r\n  return unload;\r\n}\r\n<\/pre>\n<p>In this example, we flush the logging buffers when it looks like we&#8217;re about to be unloaded. This is code that we would have to do anyway in <code>DLL_<\/code><code>PROCESS_<\/code><code>DETACH<\/code>, but we can do it here, so that the work is done outside the loader lock.<\/p>\n<p>Note that returning <code>true<\/code> from <code>winrt_<\/code><code>can_<\/code><code>unload_<\/code><code>now<\/code> doesn&#8217;t guarantee that you will be unloaded, so any work you do is speculative and may be a false alarm. You can flush the logging buffers, and possibly even close the handles, but you need to be ready for the case that the unload doesn&#8217;t actually happen, and your logging code needs to be reopen the handles if they had been closed.<\/p>\n<p>Injecting code into the <code>winrt_<\/code><code>get_<\/code><code>activation_<\/code><code>factory<\/code> can also be handy if you need to do some filtering or rerouting.<\/p>\n<pre>void* __stdcall winrt_get_activation_factory(\r\n    std::wstring_view const&amp; name)\r\n{\r\n  if (use_old_media_player &amp;&amp;\r\n      name == L\"Contoso.MediaPlayer\") {\r\n    return v1_get_activation_factory(name);\r\n  } else {\r\n    return I_get_activation_factory(name);\r\n  }\r\n}\r\n<\/pre>\n<p>In the above example, the <code>Contoso.<\/code><code>MediaPlayer<\/code> was completely rewritten between versions 1 and 2, and the implementation wants to preserve the old version as a compatibility fallback. If the DLL has decided to use the old media player, then requests for the media player will produce an object from the old implementation. Otherwise, the DLL is using the new media player, or the request is not even for the media player at all, in which case we get the object from the current implementation.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Injecting a little something extra.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-104462","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Injecting a little something extra.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/104462","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=104462"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/104462\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=104462"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=104462"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=104462"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}