Conversation
sylveon
left a comment
There was a problem hiding this comment.
winrt_to_hresult_handler and friends needs WINRT_EXPORT extern "C++" to work properly when mixing non-modules and modules code in the same final DLL/EXE
| w.write(strings::base_includes); | ||
| w.write(R"( | ||
| #if defined(__cpp_lib_modules) && defined(WINRT_IMPORT_STD) | ||
| import std; |
There was a problem hiding this comment.
Why not just omit this bit and rely on the ixx to import std first if WINRT_IMPL_MODULES is defined?
| ixx.write("#define WINRT_IMPL_GLOBAL_MODULE_FRAGMENT\n"); | ||
| ixx.write(strings::base_includes); | ||
| ixx.write("#undef WINRT_IMPL_GLOBAL_MODULE_FRAGMENT\n"); | ||
| ixx.write(strings::base_std_includes); |
There was a problem hiding this comment.
Should be able to avoid including any std header by writing import std below export module std
| @@ -0,0 +1,33 @@ | |||
|
|
|||
| // This header provides the preprocessor macros needed by generated C++/WinRT | |||
There was a problem hiding this comment.
I would suggest avoiding to repeat this code somehow, it's already in base_macros.
… on exported handlers
| // header must be included textually. | ||
|
|
||
| #ifndef WINRT_EXPORT | ||
| #define WINRT_EXPORT |
There was a problem hiding this comment.
Theorically we could omit this bit as a module would always have WINRT_EXPORT defined.
|
I tested it locally. After enabling CppWinRTModule, compiling winrt.ixx.obj failed, showing that the symbol for CoGetCallContext could not be found. Manually linking Ole32.lib resolved the issue, but the header mode does not have this problem. I'm not sure what the cause is. Additionally, if both CppWinRTModule and BuildStlModule are enabled, it will break code that uses only header files. |
You'll need to provide more info on how you configured your test project. I'm not hitting this in the test_cpp20_module project, even after adding some use of |
I downloaded the package built by GitHub CI, used the C++/WinRT console project template, installed the NuGet package, then set the C++ standard to C++20, enabled the CppWinRTModule and BuildStlModule options, removed and disabled pch, and used the following main.cpp: #include <winrt/Windows.Foundation.h>
#include <cstdio>
using namespace winrt;
using namespace Windows::Foundation;
int main()
{
init_apartment();
Uri uri(L"http://aka.ms/cppwinrt");
std::printf("Hello, %ls!\n", uri.AbsoluteUri().c_str());
}import winrt;
import std;
using namespace winrt;
using namespace Windows::Foundation;
int main()
{
init_apartment();
Uri uri(L"http://aka.ms/cppwinrt");
std::printf("Hello, %ls!\n", uri.AbsoluteUri().c_str());
}Project.zip |
|
Idk about exporting the impl namespace, feel like we should find a better solution. |
|
If exporting impl is unavoidable, I still hope to avoid a single winrt module. A slightly cleaner approach is to provide winrt.impl and winrt.base, where winrt.base imports winrt.impl but only re-exports non-impl declarations: export module winrt.base;
import winrt.impl; // Not re-exported
export namespace winrt {
using winrt::hstring;
...
}winrt.impl is intended for use only by files generated by cppwinrt, while user code should use winrt.base. And generate independent modules for each root namespace, such as winrt.Windows. |
|
My idea would be to generate the things required to produce as part of the module too, but that would eliminate the ability to share winrt.ifc between projects. |
|
Damaging the development experience just to hide the implementation is completely not worth it in my opinion, especially since users can already access them through headers anyway. Considering only the development experience in Visual Studio, we could request the MSVC and IntelliSense teams to support an attribute such as |
|
I started out exporting the impl namespace to get component authoring to work. I needed to just get things building and find out if I was hitting more MSVC module limitations, or if it was a simple fix. I'm currently investigating the feasability of splitting of winrt_base and winrt_base.impl to reduce the scope of impl exports. If that goes well, I'll also look at making the component projection a module as well, to remove the impl namespace in component code. But the big news is that I've done enough massaging on this code to get it to work in VS2022 (and VS2026 using the v143 toolset). At this point, I've got a checkpoint (9250b45) where the entire solution builds using the v143 toolset, including the 3 module test projects:
This also means that interested folks can checkout the branch and build things themselves and tinker with it. So, the TODOs are:
|
This is a draft of the initial modules support that so far seems to evade various toolchain implementation issues and builds successfully. I'm focusing on consumption, but also trying to get consumption with some basic component authoring to work as well.
Some credit goes to @sylveon and @YexuanXiao for the trailblazing they've done in their forks.
I'll continue to update and add notes as I iterate, but it's getting functional enough that publishing a draft is helpful.