Convert NVDAHelper LocalWin10 to C++/WinRT#11768
Conversation
This comment has been minimized.
This comment has been minimized.
|
CC @jcsteh, may need to test minimum Windows 10 build supported (hopefully 17134 or later). Thanks.
|
|
17134 should be supported, but I'm pretty sure that even older builds should work. I will test it against Server 2016 next week. |
|
Would any of this upset any routines used in Windows 7 or8.1?
|
|
Tested with nvda_snapshot_pr11768-21228 on Microsoft Windows [version 10.0.19041.572] in Simplified Chinese and no error messages appear. |
No. Nothing is changed for these versions of Windows. |
|
Generally I like the look of this change, but I'd like to target the 2021.1 release (and merge early for maximum testing). I'd like to mark it as a draft while we make a decision about making onecore a separate dll. |
Note that nvdaHelperLocalWin10 (which includes Win 10 OCR and OneCore speech) is already a separate dll. It previously had a separate SCons environment which allowed compiler flags to be tweaked, but this PR removes that. If you're worried about coroutine support being enabled everywhere, I'd suggest reinstating that separate SCons environment and moving the /await flag to that. Note that given the highly asynchronous nature of WinRT in general, I think most things in nvdaHelperLocalWin10 are probably going to need await sooner or later, so I think it's reasonable to enable this for the whole of nvdaHelperLocalWin10 (but not necessarily other NVDA dlls). All of that said, I can think of other places in nvdaHelper where coroutines could be useful, but it's certainly a riskier change that way. |
See test results for failed build of commit 3f58ed2f3b |
| env.Append(LINKFLAGS='/OPT:REF') #having symbols usually turns this off but we have no need for unused symbols | ||
|
|
||
| win10env = env.Clone() | ||
| # Add C++ co-routine support |
There was a problem hiding this comment.
Please add "for winrt usage" or something more specific. I haven't yet done a thorough review of this so I'm not sure I can make a precise suggestion yet. Generally, if I encountered this while trying to split up the code in this DLL or merge with another, or perhaps copy the approach for a new DLL, then I'd want to know which code / features depend on this flag and why it is necessary.
|
Hi @LeonarddeR While W10 1511 is quite old, unsupported and therefore not very important the fact that this code fails there suggests to me that it would also fail on 1507 LTSB which is still supported until October 2025 so I believe we need to support it too. In general I'd like to push back a little on this. Having more readable code is of course important but since it brings no user visible benefits merging this PR seems quite risky to me. We had similar discussion in the past on #10405 which quite similarly to this one just modernized syntax without user visible changes and all parties involved there decided that it should be closed.
BTW Were you able to test this on Server 2016? |
If properly tested, I'm not sure why this code introduces risk. We just will have to make sure that we test all of it in the full range of still supported Windows 10 builds.
There's a huge difference between Python and C++ in that C++ compiles all code before running it, which tackles most of the risk IMO. Changing Python code has a way bigger risk of experiencing regressions at run time.
True. However, they already highly recomment C++/WinRT at this point. I'd like to add that coroutine suppot in C++/WinRT is currently based on the experimental support in C++17. The current WinRT bindings in the Windows 10 SDK don't support C++20 style coroutines. We could consider this another reason to wait for this to be merged. |
|
Unfortunately with latest build from this PR Onecore driver still crashes on Windows 10 1511. Log is as follows: DEBUG - autoSettingsUtils.autoSettings.AutoSettings._registerConfigSaveAction (20:56:04.880) - MainThread (1812): ERROR - synthDriverHandler.setSynth (20:56:04.897) - MainThread (1812): |
Most of testing coverage we can get comes from Alpha users and Server versions of Windows / LTSB editions of Windows 10 are used mostly in corporate environments so I don't think many people are willing/able to use test builds in such circumstances.
Its obviously true when considering risks which comes from syntactic errors, but when it comes to regression testing our Python code has a lot of unit tests which simply does not exists for the C++ part. In essence with changes like this it is more than likely that some kind of regression will slip through especiallly for older Win 10 versions so we're trading not so pretty but certainly working (it has been written back when old versions of Win 10 were a current one so it supports them well) code for a new one which is written in a modern way but may or ma not work. |
|
Regardless what we do, I think I'd like to go to the bottom of this. I might be able to test on server 2016 later on. Could you provide output of the following on 1511? |
On the latest Alpha it returns 0, whereas with the build from this PR 1631488 is returned. |
|
Wow, there's some real weirdness going on there indeed.
|
This reverts commit 7abe8f9.
|
It looks like IsApiContractPresent panics if you provide it a regular string that's implicitly converted to a hstring. Providing it a hstring seems to fix it. @lukaszgo1 could you verify? |
|
Yes, OneCore works correctly using latest build on 1511. |
|
@feerrenrut I hope I have addressed all the review concerns. |
Co-authored-by: Reef Turner <feerrenrut@users.noreply.github.com>
Co-authored-by: Reef Turner <feerrenrut@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
feerrenrut
left a comment
There was a problem hiding this comment.
Let's leave the other more complicated design changes for a follow up. With these minor fixes I propose we merge.
Co-authored-by: Reef Turner <feerrenrut@users.noreply.github.com>
…3072) 1. Visual Studio has support for C++20. 2. WinRT is C++20 (#11768). 3. Compiling with C++20 ensures code is more conformant. - Passing string literals to parameters expecting `wchar_t*` or `BSTR` is no longer supported. This ensures safe code, for a rationale see: https://docs.microsoft.com/en-us/cpp/build/reference/zc-strictstrings-disable-string-literal-type-conversion?view=msvc-170 - The `/permissive-` flag (note the minus symbol disabling permissive mode), ensuring conformance in more areas. See: https://docs.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance?view=msvc-170 This change: - Updates build params so `nvdaHelper` is built with C++20 and disable permissive mode. - Fix errors (`wchar_t*` or `BSTR` from string literal)
Link to issue number:
Closes #10662
Summary of the issue:
Interaction with the Windows 10 UWP/OneCore APIs was performed using C++/CX code. This is an extension to the C++ language that which dialect is sometimes a bit different from standard C++.
C++/CX is superseded by C++/WinRT. which is a C++20 language projection. Using this results in code that is IMO much more readable to people who know C++ but are not accustomed to the CX dialect. It also uses C++ coroutines instead of the Parallel Patterns Library. Not to mention that CX is likely to be deprecated in the future.
Description of how this pull request fixes the issue:
This pr converts all C++/CX and WRL code to its equivalent in C++/WinRT. While at it, I converted the OcSpeech and UwpOcr structs to classes that hold the speech synthesis and ocr engines as private members, ensuring that the exported functions could only access the things they need.
Testing performed:
Tested both OCR and OneCore on a local system on Windows 10 19H1, 19H2 and 20H1. All seemed to work fine. See below for checklist
Known issues with pull request:
None known
Change log entry:
Code Review Checklist: