Windows Phone 7.5 ネイティブコードプログラミング

執筆: つやつや

日時: 2011-08-31 (水) 8:27 PM

Windows Phone 7.5 でどうしてもネイティブコードを使いたい開発者のために、簡単な解説を書いてみました。

image

一般的に、Windows Phone 7 および 7.5 ではネイティブコードを使った開発はできないと説明されています。

しかし、それはマーケットプレイスの審査に落ちるという意味であって、個人的な開発や野良アプリの開発には問題ないはずです。

また、キャリアやメーカーなど、Microsoft から許可された場合はネイティブコードを使ったアプリをマーケットプレイスで配布することができます。

Windows Phone 7.5 の GAC には、以前と同じく Microsoft.Phone.InteropServices.dll が存在しており、COM 相互運用のための機能が用意されています。これを使えば、マネージコードから COM の仕組みを使ってネイティブ DLL を呼び出すことができます。

COM 呼び出しの手順

Windows Phone 7.5 においても、COM 呼び出しの方法はあまり変わっていないようです。ここでは、KDDI のアプリ「アドレス帳移行」が、どのように COM を使用しているか調査してみました。

このアプリは、ContactsTransferModel.dll というマネージアセンブリ内の ShiftJisToUnicode クラスから、ToUnicodeConverter.dll という COM DLL を呼び出しています。どうやら Shift JIS エンコードされたバイト配列を Unicode 文字列に変換するために使っているようです。

まずは COM インターフェイス、メソッド、COM クラスを定義しています。

[ComImport, Guid("0DD47341-CC9E-42d7-BDFA-A185899B44FD"),
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IUnicodeConverter {
    uint ToUnicodeString(
        uint codePage,
        ref byte byteArray,
        int byteArrayLength,
        out string unicodeString);
}

[ComImport, Guid("FD01B823-FB6C-418b-A03B-0537A2255672"),
    ClassInterface(ClassInterfaceType.None)]
private class UnicodeConverter {
}

 

次に、実際にインスタンスを生成するところです。

ComBridge.RegisterComDll("ToUnicodeConverter.dll", new Guid("FD01B823-FB6C-418b-A03B-0537A2255672"));
this.converter = (IUnicodeConverter) new UnicodeConverter();

 

ここでは、Microsoft.Phone.InteropServices アセンブリの ComBridge クラスを使って、DLL を登録しています。指定は相対パスとなっており、DLL がアプリのルートフォルダにあればファイル名を書くだけです。

this.converter というのは、IUnicodeConverter 型のインスタンス変数です。UnicodeConverter クラスのインスタンス生成に成功すれば、自由に COM DLL のメソッドを呼び出すことができます。

自分のアプリで使う方法

ためしに ToUnicodeConverter.dll を自作のアプリで呼び出してみたところ、とくに問題なく動作しました。

プロジェクトはごく一般的な Silverlight for Windows Phone アプリ (C#) ですが、次のような準備をしています。

  • 参照設定で Microsoft.Phone.InteropServices.dll を参照する
  • プロジェクトのルートに ToUnicodeConverter.dll を置く
  • プロジェクトのルートに WPInteropManifest.xml を置く

なお、Mango では WMAppManifest.xml に ID_CAP_INTEROPSERVICES を追加する必要はありません。(逆に、これがあるとデプロイ時に 0×81030120 エラーが発生します)

念のため ToUnicodeConverter.dll からデジタル署名を外した状態でも試してみましたが、とくに問題ありませんでした。

 

ちなみにこのコードは実機でのみ有効です。エミュレータでは動作しません。

エミュレータの場合、 RegisterComDll には成功しますが、COM インスタンスを生成しようとすると、コンストラクタで COMException がスローされます。

COM object with CLSID ‘{FD01B823-FB6C-418B-A03B-0537A2255672}’ cannot be created due to the following error: The request is not supported. .

 

残念ながら「アドレス帳移行」にはレジストリやファイルシステムを操作する DLL は含まれていませんでした。今後リリースされるアプリに注目したいところです。

管理人コメント:

早くレジストリをいじってシトラスのタイルカラーをもう少し暗くしたいわー

この記事のタグ: , ,

7 個のコメントがあります

  1. WP7.5のアプリ開発を始めたばかりの職業プログラマです。S-JIS->UTF8の文字コード変換クラスがインタフェースのみ。メソッドは実装されていないことがわかり、泣きながら(笑)情報を検索してこちらにたどり着きました。

    教えていただきたいのですが、このToUnicodeConverter.dllはKDDI社の所有物でしょうか。nanaphoさんはこれをどのようにして入手されたのですか?

    どうしてもネイティブコードを使いたいというわけではなく、マネージドコードですむならその方がいいと思っているのですが、まずはあらゆる可能性をリストアップしてみようと思っています。

    かの

    2011-08-31 (水) 8:27 PM

    このコメントへのリンク

  2. tmyt さんの JpEncoding を使ってみてはどうでしょうか。
    http://d.hatena.ne.jp/tmyt/20110530/1306763923

    tezawaly

    2011-08-31 (水) 8:27 PM

    このコメントへのリンク

  3. [...] Read more about the discovery at Nanapho.jp here. [...]

  4. ありがとうございます。ではさっそく。

    かの

    2011-08-31 (水) 8:27 PM

    このコメントへのリンク

  5. [...] file. If your interested in doing this for yourself, then we have a tutorial here for you. You will need to remember that this is for homebrew phones and so do this with caution and [...]

  6. [...] Source: Nanapho.jp [...]

  7. JpEncodingを組み込んで解決しました。助かりました。ありがとうございます。

    かの

    2011-08-31 (水) 8:27 PM

    このコメントへのリンク

Leave a Reply