モノトーンの伝説日記

Apex Legends, Splatoon, Programming, and so on...

Portable Class Library Trick。(.NET, C#, PCL など…)

 ふへへ、いい考えがわいてくる。てか、この方法知らないがゆえに道がふさがってしまっている感があるぞ!!!!! ということで見ていきましょう。

概要

  1. 元ネタ
  2. 雑談
  3. どういうことなのか
  4. 実践
  5. まとめ

0. 元ネタ

 元ネタ「Xamarinと、ポータブル・クラス・ライブラリ(PCL)

 ありがとう元ネタ。いい発想が思いついたよ。

1. 雑談

 この記事を見て、次の瞬間、私は手を動かしていた。そう、PCL に関してね。

 「Xamarin でこんなことやってる、なるほど、fmfm… なら、実際にこれをやってみてうまく動くか確認して、…」

 ということでやってみた。

2. どういうことなのか

 PCL はあくまでも IL コードを吸収しているわけではないので、同一アセンブリー名、名前空間を持てば非 PCL なものになろうがそれは呼び出すライブラリーからは同じ定義なので違和感がないのである。つまり、

f:id:mntone:20140630120444p:plain

 図を見たらお分かりいただけただろうか? 名前はそっくり、だけど Win32 でしか使えない X にすり替えているだけです。注意すべきことは、WinRT のコンパイル時、直接プロジェクトを参照するとまずいみたいです。つまり DLL を参照すればおkみたい。たとえば、unsafe で高速化したい部分を切り出して開発したりすることも可能である。

3. 実践

 まず、ライブラリー的な簡単なコードとして、メッセージを送り出すクラスを作ってみよう。

using System;
#if WINDOWS_APP
using Windows.UI.Popups;
#endif

namespace MessagerNS
{
    public static class Messager
    {
        public static void Send( string data )
        {
#if WINDOWS_CLASSIC
            Console.WriteLine( data );
#elif WINDOWS_APP    
            var md = new MessageDialog( data );
            md.ShowAsync();
#else
            throw new NotImplementedException();
#endif
        }
    }
}

 次に、この PCL を呼び出すライブラリーを作ります。

using MessagerNS;

namespace MessagerTesterNS
{
    public sealed class MessagerTester
    {
        public MessagerTester()
        {
            Messager.Send( "send!!!" );
        }
    }
}

 さらに、これを参照するプロジェクト (Win32/WinRT) を作ります。

Win32

using MessagerTesterNS;
using System;

namespace MessagerTesterWin32
{
    class Program
    {
        static void Main( string[] args )
        {
            new MessagerTester();
            Console.ReadKey( true );
        }
    }
}

WinRT

using MessagerTesterNS;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace MessagerTesterWinRT
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        private void OnPageLoaded( object sender, RoutedEventArgs e )
        {
            new MessagerTester();
        }
    }
}

 以上です。

4. まとめ

 全体的に PCL にして、一番パフォーマンスにかかわる部分を unsafe な ptr コードにしたり、プラットフォームに依存する機能を使いたい場合、このようなコードでラップしてあげるとうまくいく。

 これに関していろいろ試行錯誤したプロジェクトを挙げておく。時間があれば、SilverlightWPF, WinForms なども追加すると面白いかもですね。

mntone/PclTrickSample · GitHub

f:id:mntone:20140630121843p:plain