Совместное использование статической библиотеки в приложениях Win8 и WP8

У меня есть статическая библиотека, написанная на C ++, которую я хочу сделать доступной для приложений Windows 8 и Windows Phone 8, написанных на .NET.

Я хотел бы свести к минимуму количество отдельных проектов, которые нужно поддерживать, настроив свое решение примерно так:

Попытка №1: только проекты пользовательского интерфейса зависят от платформы

MySolution.sln
|
+- Library                    (virtual folder to group projects below)
|  |
|  +- LegacyLib.vcxproj       Static Library project - Platform-independant, native C++ code using STL & CRT. Just enough C++/CX to make some types available to .NET and expose a few static methods.
|  |
|  +- LegacyPcl.csproj        Portable Class Library project - References LegacyLib, adds some types, wrappers, interfaces, etc. written in C#.
|
+- SampleApp                  (virtual folder to group projects below)
   |
   +- CommonAppSrc            Platform-independant C# source code (e.g. MVVM classes for Model and ViewModel).
   |
   +- SampleApp_Win8.csproj   Platform-specific App project - References LegacyPcl, includes files from CommonAppSrc using "Add as Link".
   |
   +- SampleApp_Wp8.csproj    Platform-specific App project - References LegacyPcl, includes files from CommonAppSrc using "Add as Link".

Проблема: кажется, что переносимые библиотеки классов не поддерживают включение нативного кода C ++ в любой форме.

Один из предлагаемых способов включения встроенного C ++ в ваши приложения для Windows 8 и Windows Phone 8 - это создание компонента среды выполнения Windows. К сожалению, проекты WRC, ориентированные на Win8 и Wp8, относятся к разным типам проектов; Нет возможности создать компонент среды выполнения Windows, предназначенный для нескольких платформ.

Итак, создание проекта компонента среды выполнения Windows для каждой целевой платформы дает следующее:

Попытка №2 - проекты пользовательского интерфейса зависят от платформы, как и оболочка LegacyLib.

MySolution.sln
|
+- Library                    (virtual folder to group projects below)
|  |
|  +- LegacyLib.vcxproj       Static Library project - Platform-independant, native C++ code using STL & CRT. Just enough C++/CX to make some types available to .NET and expose a few static methods.
|  |
|  +- LegacyWrc_Win8.csproj   Platform-specific Windows Runtime Component project - References LegacyLib, adds some types, wrappers, interfaces, etc. written in C#.
|  |
|  +- LegacyWrc_Wp8.csproj    Platform-specific Windows Runtime Component project - References LegacyLib, adds some types, wrappers, interfaces, etc. written in C#.
|
+- SampleApp                  (virtual folder to group projects below)
   |
   +- CommonAppSrc            C# source code (e.g. Model and ViewModel classes).
   |
   +- SampleApp_Win8.csproj   Platform-specific App project - References LegacyWrc_Win8, includes files from CommonAppSrc using "Add as Link".
   |
   +- SampleApp_Wp8.csproj    Platform-specific App project - References LegacyWrc_Wp8, includes files from CommonAppSrc using "Add as Link".

Проблема: когда я пытаюсь сослаться на LegacyLib из проекта LegacyWrc_Win8; Я вижу следующее предупреждение:

Добавлять ссылку на «LegacyLib» не рекомендуется, поскольку он несовместим с приложениями Магазина Windows.

Среда сборки сообщает, что для обеспечения совместимости статической библиотеки LegacyLib с моим компонентом среды выполнения Windows Win8 я должен включить поддержку приложений Магазина Windows в конфигурации проекта LegacyLib (игнорирование предупреждения приводит только к ошибке позже. ):

  • Свойства проекта> Свойства конфигурации> Общие> Параметры проекта по умолчанию
  • Установите для Поддержка приложений Магазина Windows значение Да.

Затем, когда я пытаюсь сделать то же самое с проектом LegacyWrc_Wp8, я получаю следующую ошибку:

Ссылка на LegacyLib не может быть добавлена, потому что два проекта нацелены на разные платформы.

Таким образом, обеспечение совместимости статической библиотеки с Windows 8 сделало ее несовместимой с Windows 8 Phone.

Похоже, что просто невозможно создать единую статическую библиотеку, которая могла бы использоваться этими двумя разными платформами, даже если сама библиотека не содержит кода для конкретной платформы.

Мне не обязательно поддерживать параллельные версии исходного кода, но я должен создать / поддерживать два отдельных проекта, каждый из которых создает платформенно-зависимую версию статической библиотеки.

У моего решения теперь есть версия каждого проекта для конкретной платформы:

Попытка №3 - КАЖДЫЙ ПРОЕКТ зависит от платформы

MySolution.sln
|
+- Library                        (virtual folder to group projects below)
|  |
|  +- NativeCode                  (virtual folder to group projects below)
|  |  |
|  |  +- CommonLibSrc             Native C++ source code using STL & CRT. Just enough C++/CX to make some types available to .NET and expose a few static methods.
|  |  |
|  |  +- LegacyLib_Win8.vcxproj   Platform-specific Static Library project - Includes files from CommonLibSrc using "Add as Link".
|  |  |
|  |  +- LegacyLib_Wp8.vcxproj    Platform-specific Static Library project - Includes files from CommonLibSrc using "Add as Link".
|  |
|  +- DotNetWrapper               (virtual folder to group projects below)
|     |
|     +- CommonWrcSrc             Platform-independant C# source code (types, wrappers, interfaces, etc. for LegacyLib support) for the Windows Runtime Component projects.
|     |
|     +- LegacyWrc_Win8.csproj    Platform-specific Windows Runtime Component project - References LegacyLib_Win8, includes files from CommonWrcSrc using "Add as Link".
|     |
|     +- LegacyWrc_Wp8.csproj     Platform-specific Windows Runtime Component project - References LegacyLib_Wp8, includes files from CommonWrcSrc using "Add as Link".
|
+- SampleApp                      (virtual folder to group projects below)
   |
   +- CommonAppSrc                Platform-independant C# source code (e.g. Model, ViewModel).
   |
   +- SampleApp_Win8.csproj       Platform-specific App project - References LegacyWrc_Win8, includes files from CommonAppSrc using "Add as Link".
   |
   +- SampleApp_Wp8.csproj        Platform-specific App project - References LegacyWrc_Wp8, includes files from CommonAppSrc using "Add as Link".

Проблема: я пока ничего не вижу (кроме того, что это уродливо и требует более сложного обслуживания).

Кстати, я изучал возможность использования конфигураций сборки, но они уже используются для комбинаций Debug / Release и x86 / ARM. Добавление Win8 / Wp8 в микс снова просто удваивает конфигурации, и вы сместили, а не уменьшили бремя обслуживания.

Я что-то упускаю? Похоже, это обычное дело. Кто-нибудь еще прошел через это и придумал альтернативные / лучшие способы сделать это?

РЕДАКТИРОВАТЬ ДЛЯ Полноты

Вот что я в итоге сделал ...

MySolution.sln
|
+- LegacyApiLib               (virtual folder to group projects below)
|  |
|  +- CommonCppSource         Common C++ source code used by LegacyWrc_*.vcxproj projects
|  |                          below
|  |
|  +- LegacyPcl.csproj        Portable class library with C# API interfaces only; no
|  |                          implementation classes.
|  |
|  +- LegacyWrc_Win8.vcxproj  Platform-specific Windows Runtime Component project - includes
|  |                          legacy C++ files, and uses C++/CX to expose static methods and
|  |                          classes to .NET in Win8.
|  |
|  +- LegacyWrc_Wp8.vcxproj   Platform-specific Windows Runtime Component project - includes
|                             legacy C++ files, and uses C++/CX to expose static methods and
|                             classes to .NET in WP8.
|
+- SampleApp                  (virtual folder to group projects below)
   |
   +- SampleAppBL.csproj      Portable class library containing the app's business logic.
   |                          References LegacyPcl.csproj for legacy API interface definitions.
   |                          Business logic is written against those interfaces; never against
   |                          specific classes. The Win8 or WP8 apps will reference the
   |                          appropriate Windows Runtime Component project, create or register
   |                          the concrete classes that implement the legacy API interface, and
   |                          either pass it into the BL or register it with IOC mechanism. In
   |                          this way, SampleAppBL.csproj never has to know about (or
   |                          reference) any of the WRC projects. 
   |
   +- SampleAppUI_Win8.csproj Platform-specific App project - References LegacyWrc_Win8.vcxproj
   |                          and SampleAppBL. Contains minimal platform-specific Win8 UI code.
   |
   +- SampleAppUI_Wp8.csproj  Platform-specific App project - References LegacyWrc_Wp8.vcxproj
                              and SampleAppBL. Contains minimal platform-specific WP8 UI code.

Я понял, что несколько вспомогательных классов, которые экспортирует LegacyApiLib, можно написать на управляемом C ++ вместо C #. Это означало, что я мог просто связать их с проектами WRC, что немного упростило ситуацию.


person Scott Smith    schedule 01.07.2013    source источник


Ответы (1)


Как вы обнаружили, собственная библиотека должна быть скомпилирована отдельно для каждой платформы, поэтому на нее нельзя напрямую ссылаться из переносимой библиотеки классов.

Я бы предложил использовать шаблон абстракции, чтобы вы могли делиться большей частью вашего .NET-кода (то есть моделями и моделями представлений) через Portable Class Library. В PCL создайте интерфейсы или абстрактные классы для функций, которые вы предоставляете в собственной библиотеке. Затем реализуйте их в проектах для конкретной платформы, которые перенаправляют вызовы в собственную библиотеку. Наконец, используйте внедрение зависимостей, чтобы подключить реализации этих интерфейсов, чтобы вы могли вызывать их из общего PCL.

Вот несколько сообщений в блоге, посвященных этому:

person Daniel Plaisted    schedule 01.07.2013