連載:深入り.NETプログラミングアンマネージ・コードの型情報と連携するNyaRuRuMicrosoft MVP Windows - DirectX(Jan 2004 - Dec 2009) 2009/07/21 |
Page1
Page2
|
C#やVisual Basicなどのコードからアンマネージ・コード(ネイティブ・コード)を呼び出すための「P/Invoke(Platform Invoke、プラットフォーム呼び出し)」には定型作業が多い。例えばC/C++用のマクロ定数は、C#ではenum型として扱いたいところだ。これには例えば次のような書き換えが必要になる。
|
|
C/C++用のマクロ定数定義の例 |
|
|
C/C++用のマクロ定数をC#のenum型で表現した例 |
これを実現する安直な方法は、この作業をすべて手で行うというものだ。まずはオリジナルのC/C++コードをC#コード上にコピーし、微妙な文法の違いを行ごとに書き換えていく。義務感に駆られて<summary>タグによるドキュメント・コメントも付け始めると、作業量はさらに増える。Document Explorerで該当するドキュメントを探し、ドキュメント・コメントに1つ1つコピーすれば、とても親切なP/Invokeコードが出来上がることだろう。
このような手作業方式は、ひたすらに手を動かすだけあって、なんだかずいぶん仕事をした気になってしまう。筆者もよく現実逃避にP/Invokeコードを書いてしまうのだが、自戒も込めて、こんな逃避先はつぶしてしまいたい。というわけで、今回はC/C++と.NETの橋渡しに関する使えそうな技術を紹介しよう。
【コラム】エディタの機能で楽をする |
たいていのエディタには、記録したキー操作を繰り返すマクロ機能や、強力なテキスト置換の機能が付いている。うまく一発で変換できるマクロを作れたときの達成感はひとしおだ。これまた仕事をした気になってしまう。 |
【コラム】pinvoke.net |
P/Invokeといえば、http://pinvoke.netに投稿されているコードを使うという方法もある。筆者はあまりこのサイトを使っていないのだが、深い理由があるわけではなく、ドキュメント・コメントの付け方がまちまちであったり、SafeHandle型を使うべきところでIntPtr型を使っているものが混ざっていたりと、コードの質がバラバラなのが単に気になるというだけである。なお、一部のAPIには非常に詳細な解説が付いており、それが忘れていたことや重要な注意点を思い出させてくれることもある。 |
■P/Invoke Interop Assistant
P/Invokeには、実に便利なツールがすでにある。Code Plex上のCLR Interopチームのサイトで公開されている「P/Invoke Interop Assistant」というツールは、P/Invokeまたは、逆P/Invokeで用いる型定義の自動生成を行ってくれる。
図2 P/Invoke Interop Assistantの実行例:[SigImp Translate Snippet]タブ |
[SigImp Translate Snippet]タブからは、C++のソース・コードを基に、その場でP/Invokeコードを生成することもできる。例えばビット・フィールドを用いた構造体もこのとおり。 |
さて、P/Invoke Interop Assistantはどのようにコードを生成しているのだろうか? ソース・コードが公開されているので、その実装方法を調べてみた。
結論からいえば、P/Invoke Interop AssistantはC/C++用の「手書きパーサー」を内蔵している。ただし、C/C++文法を完全に網羅しているわけではなく、あくまでWindows SDKのヘッダ・ファイルに登場する程度の文法をサポートするぐらいのものと考えればよいだろう。それでも大仕事である。それを既存のライブラリを一切使わず、自前のパーサーでやってのけるのには恐れ入る。テストもしっかり書かれており、PInvokeTool\UnmanagedToManaged\PInvokeTest\SampleFiles以下に定義されているテスト・ケースは58にも及ぶ。ちなみにこのパーサー、実装言語はVisual Basicである。
また、プリプロセッサ・マクロの解釈も部分的にサポートしている。先ほど「#define」で定義された定数の取り込みに成功していたことを思い出してほしい。Windows SDKのヘッダ・ファイルというある種のDSL(ドメイン特定言語)のインポートに特化したパーサーといえる。
INDEX | ||
[連載]深入り.NETプログラミング | ||
アンマネージ・コードの型情報と連携する | ||
1.C/C++と.NETの橋渡し/P/Invoke Interop Assistant | ||
2.Standard Annotation Language(SAL)/デバッグ・シンボル | ||
「深入り.NETプログラミング」 |
- 第2回 簡潔なコーディングのために (2017/7/26)
ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている - 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう - 第1回 明瞭なコーディングのために (2017/7/19)
C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える - Presentation Translator (2017/7/18)
Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|