5

C++ で記述された静的ライブラリがあり、.NET で記述された Windows 8 および Windows Phone 8 アプリケーションで利用できるようにしたいと考えています。

次のようなソリューションを設定することで、維持する個別のプロジェクトの数を最小限に抑えたいと思います。

試行 #1: UI プロジェクトのみがプラットフォーム固有です

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++ コードのいかなる形式のインクルードもサポートしていないようです。

Windows 8 および Windows Phone 8 アプリにネイティブ C++ を含めるための推奨される方法の 1 つは、Windows ランタイム コンポーネントを作成することです。残念ながら、Win8 と Wp8 を対象とする WRC プロジェクトは異なるプロジェクト タイプです。複数のプラットフォームを対象とする Windows ランタイム コンポーネントを作成するオプションはありません

したがって、ターゲット プラットフォームごとに Windows ランタイム コンポーネント プロジェクトを作成すると、次のようになります。

試み #2 - UI プロジェクトはプラットフォーム固有であり、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".

問題: LegacyWrc_Win8 プロジェクトから LegacyLib を参照しようとすると、次の警告が表示されます。

Windows ストア アプリと互換性がないため、「LegacyLib」への参照を追加することはお勧めしません。

ビルド環境は、LegacyLib 静的ライブラリを Win8 Windows ランタイム コンポーネントと互換性があるようにするには、LegacyLib プロジェクト構成でWindows ストア アプリ サポートを有効にする必要があると言っています (警告を無視すると、後でエラーが発生するだけです)。

  • プロジェクト プロパティ>構成プロパティ>一般>プロジェクトの既定値
  • Windows ストア アプリのサポートはいに設定する

次に、LegacyWrc_Wp8 プロジェクトで同じことをしようとすると、次のエラーが発生します。

2 つのプロジェクトが異なるプラットフォームを対象としているため、「LegacyLib」への参照を追加できません。

そのため、静的ライブラリを Windows 8 と互換性があるようにすると、Windows 8 Phone との互換性がなくなりました。

ライブラリ自体にプラットフォーム固有のコードが含まれていなくても、これら 2 つの異なるプラットフォームで使用できる単一の静的ライブラリを構築することは不可能のようです。

ソース コードの並行バージョンを維持する必要は必ずしもありませんが、それぞれがプラットフォーム固有のバージョンの静的ライブラリをビルドする 2 つの個別のプロジェクトを作成/維持する必要があります。

私のソリューションには、すべてのプロジェクトのプラットフォーム固有のバージョンがあります。

試行 #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".

問題:これまでに確認できるものはありません (これが見苦しく、メンテナンスが必要であるという事実を除いて)。

ところで、ビルド構成を使用する可能性を調べましたが、それらは既にデバッグ/リリースと x86/ARM の組み合わせに使用されています。Win8/Wp8 をミックスに追加すると、構成が再び 2 倍になり、メンテナンスの負担が軽減されるどころか、移行されます。

何か不足していますか?これがやりたいと思うのは一般的なことのようです。他の誰かがこれを経験し、これを行う代替/より良い方法を思いつきましたか?

完全性のために編集

これが私がやったことです...

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 プロジェクトにバンドルするだけでよいことを意味し、物事を少し単純化しました。

4

1 に答える 1

2

お気づきのように、ネイティブ ライブラリはプラットフォームごとに個別にコンパイルする必要があるため、ポータブル クラス ライブラリから直接参照することはできません。

抽象化パターンを使用して、ほとんどの .NET コード (つまり、モデルとビュー モデル) をポータブル クラス ライブラリ経由で共有できるようにすることをお勧めします。PCL では、ネイティブ ライブラリで公開する機能のインターフェイスまたは抽象クラスを作成します。次に、呼び出しをネイティブ ライブラリに転送するプラットフォーム固有のプロジェクトにそれらを実装します。最後に、依存性注入を使用してこれらのインターフェイスの実装を接続し、共有 PCL から呼び出すことができるようにします。

これをカバーするいくつかのブログ投稿を次に示します。

于 2013-07-01T17:00:28.987 に答える