Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge multiple CsWinRT components together to reduce package size #1914

Open
lyf6lyf opened this issue Feb 6, 2025 · 3 comments
Open

Merge multiple CsWinRT components together to reduce package size #1914

lyf6lyf opened this issue Feb 6, 2025 · 3 comments

Comments

@lyf6lyf
Copy link

lyf6lyf commented Feb 6, 2025

I am migrating a MFC C++ app to C#. I need to migrate several C++ components.
I follow https://github.com/MichalStrehovsky/CppPublishAotReference to enable AOT.

It works well for the first component.

If I do same thing for the 2nd component, there will be two component dlls. Both of them contains the DotNet runtime code.

How can I merge the components into one dll, so that they can share the runtime code and reduce the package size?

I've tried solutions:

  1. Make project A and project B both CsWinRT component, and then let A reference B. It is Failed to build.
  2. Make project A CsWinRT component, and let A reference B. project A can be built, but the types in project B are not exported.
  3. Make CsWinRT component C, and let C reference A and B. In C, create proxy types for all public types in A and B. It can work, but requires many additional code.
@manodasanW
Copy link
Member

There are a couple options. You should be able to do option 1, I am curious what error you got. But you can make use of the CsWinRTMergeReferencedActivationFactories property to make project A act as also the activation factory for Project B by merging them. This does mean to activate Project B types, the implementation DLL would be the Project A DLL. Option 3 can also work with this too I believe without you having to do the work to create proxy types as merging the activation factories would do that.

@lyf6lyf
Copy link
Author

lyf6lyf commented Feb 10, 2025

@manodasanW I created a sample app here, with option 1 + CsWinRTMergeReferencedActivationFactories . But I am not able to consume ClassB in main.cpp. ClassB is not merged into winrt\LibA.h, and there is no winrt\LibB.h generated.
How can I consume ClassB in the C++ project?

Another question is, how can I consume ClassB in project A?
Previously, I saw the build is failed because I added <CsWinRTIncludes>LibB</CsWinRTIncludes> in project A, so that I can consume ClassB. The error is

error CsWinRT1001: A public type has a namespace ('LibB') that shares no common prefix with other namespaces ('LibA'). All types within a Windows Metadata file must exist in a sub namespace of the namespace that is implied by the file name.

What is the right way to consume ClassB in project A?

@lyf6lyf
Copy link
Author

lyf6lyf commented Feb 10, 2025

Now I tried adding

<CppWinRTDynamicProjectWinMDReferences Include="$(NativeLibraryOutputFolder1)\LibB.winmd">
    <WinMDPath>$(NativeLibraryOutputFolder1)\LibB.winmd</WinMDPath>
</CppWinRTDynamicProjectWinMDReferences>

to the C++ project commit. IT generates winrt\LibB.h and I can use it in the C++ project.
But when I run it, I got a winrt::hresult_class_not_available error. It seems ClassB is not in LibA.dll.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants