Terminal: Can we remove ATL dependencies?

Created on 10 May 2019  Â·  7Comments  Â·  Source: microsoft/terminal

OK. The ATL/MFC dependency we seem to have here is super gross.

Can anyone run around and:

  1. Investigate what is actually using ATL in our project
  2. Come up with a proposal for changing it to use something that isn't ATL (because I presume it's something dumb like a CComPtr that could easily be replaced with another non-ATL ComPtr class)
  3. If it is just the ComPtr, then change it over in a PR.
Area-Build Help Wanted Issue-Task Product-Conhost Resolution-Fix-Committed

Most helpful comment

So for error handling, we have three ways: exceptions, HRESULT, and NTSTATUS. We've been trying to remove as much of the NTSTATUS usage as possible since it tends to cause problems when we mix HRESULT and NTSTATUS.

Exceptions can be used internally but they can't be leaked out publicly, such as through any of the ApiDispatchers in /src/server.

If a function can only return a single HRESULT (like S_OK) then it's better off being a function with a void return type then one that returns an HRESULT. We do have some implementations of interfaces that only return a single HRESULT but since it's required by the interface to return something they get a bit of a pass.

Any function that returns a status code of some sort must be marked noexcept and have the [[nodiscard]] attribute applied to it, unless there is some compelling reason why it can't (interop with C code for instance, or is implementing an API outside of our control).

Actually, we do have another status code, BOOL. I think this is mainly restricted to ConhostInternalGetSet and whatever interface it's implementing. This is something that I feel should be fixed up but hasn't been gotten around to yet. I'd also like to see us get rid of the mixed usage of bool, BOOL, and BOOLEAN as much as possible.

All 7 comments

Eh, it's a bit more complicated than CComPtr:

  • TSF also uses CComQIPtr and CComBSTR
  • The fuzzer uses CStringA and CComAllocator. It also includes atlcoll.h but apparently doesn't use it.

Needless to say that they all can be replaced but there aren't any "drop in" replacements. There's VC++'s own _com_ptr_t and _bstr_t classes but they're not quite like CComPtr and CComBSTR. winrt has a com_ptr but no bstr it seems.

As for CStringA, that surely won't be replaced by std::string without a fight. Kind of strange that the fuzzer doesn't already use std::string considering that it's already pretty C++ish.

Not sure if it's worth the trouble, these are all header only dependencies and AFAIR ATL headers are always installed so...

wil/com.h provides replacements for CComQIPtr . wil::com_ptr, wil::com_query, wil::com_try_query, com_ptr.query(), .try_query(), etc.

IUnknown* obj;
auto objPersist = wil::com_query<IPersist>(obj);

wil::com_ptr<IUnknown> unk;
auto other = unk.query<IOther>();

see the tests for examples.

Thanks, wil::com_ptr_nothrow (I don't think this codebase will want to deal with exceptions) looks like the best choice. The only "missing" feature would be a direct equivalent to CComPtr::CoCreateInstance - wil's own CoCreateInstance swallows the HRESULT. But the ::CoCreateInstance function works just fine.

As for CComBSTR, it turns out that there's no real need for BSTRs and std::wstring can be used instead.

exceptions... if your using std::wstring you are using exceptions. go all in (this is our position for windows).

I see we should normalize on wil instead of WRL (watching the //build video I see lots of use of WRL). Much better than ATL but wil covers this ground better.

Yeah, we have exceptions here... but we do have some exception boundaries, which @adiviness is better qualified to speak on. There’s a document about exceptions in the /doc folder.

@ChrisGuzak is there a WIL version of WRL::RuntimeClass and the module management stuff? I think wil is great, but I’m hesitant to go from “that one component that uses ATL for COM” to “that one component that still doesn’t use WRL for COM” and keep a mixed-paradigm codebase...

exceptions... if your using std::wstring you are using exceptions. go all in (this is our position for windows).

Hmm, right. And as far as I can tell most wil::com_ptr members don't actually throw exceptions anyway. Only a few do and the ones relevant to TSF (query) have "try" versions.

So for error handling, we have three ways: exceptions, HRESULT, and NTSTATUS. We've been trying to remove as much of the NTSTATUS usage as possible since it tends to cause problems when we mix HRESULT and NTSTATUS.

Exceptions can be used internally but they can't be leaked out publicly, such as through any of the ApiDispatchers in /src/server.

If a function can only return a single HRESULT (like S_OK) then it's better off being a function with a void return type then one that returns an HRESULT. We do have some implementations of interfaces that only return a single HRESULT but since it's required by the interface to return something they get a bit of a pass.

Any function that returns a status code of some sort must be marked noexcept and have the [[nodiscard]] attribute applied to it, unless there is some compelling reason why it can't (interop with C code for instance, or is implementing an API outside of our control).

Actually, we do have another status code, BOOL. I think this is mainly restricted to ConhostInternalGetSet and whatever interface it's implementing. This is something that I feel should be fixed up but hasn't been gotten around to yet. I'd also like to see us get rid of the mixed usage of bool, BOOL, and BOOLEAN as much as possible.

Was this page helpful?
0 / 5 - 0 ratings