コンテンツへスキップ
ものがたり
戻る

2009-07-01

minvoke

http://squeedlyspooch.com/blog/2009/06/29/minvoke-forcing-portability/

世の中には、せっかく.NET向けにC#で書かれたプログラムなのに、user32.dllやkernel32.dllをP/InvokeしているせいでMono/Linux環境で実行出来ない残念なアプリケーションが少なからず存在する。そしてこれらのP/Invokeは大したメリットも無く使われていることが多いし、何らかのmanaged codeで代用することも多い。

それならば、そんな邪魔なP/Invokeはアセンブリレベルで書き換えて消してしまえ、というのが、最近新しく作られたminvokeというプロジェクトだ。

これはcecilを使って、DllImportされているメンバーへの呼び出しを、minvokeで読み込んだアセンブリの中で対応するクラスのメンバーへの呼び出しに置き換える。現状では、MapDllImportAttributeというのを指定するかたちで使うようだ。minvokeがアセンブリをどう読み込むかは今後変わっていくだろうけど、kernel32やuser32に対応するクラスを含むアセンブリは、いずれmono本体に入ることになると予測されている。

さて。

P/Invokeまわりはややこしい状況なので、少し整理しながらminvokeの位置付けを補足したいと思う。

まず、P/Invokeがあること自体は必ずしも移植性を損なうものではない。呼び出されるライブラリがクロスプラットフォームであれば、ほぼ問題なく実行出来る1。一番分かりやすい例として、Gtk#はGtk+のライブラリに対するP/Invokeとして書かれている。openglまわりのバインディングもクロスプラットフォームだ。

呼び出されるライブラリのファイル名が微妙に違うせいでDllImportAttributeが上手く書けないというのは、大して問題ではない。configファイルにという(.NETには無い)要素を追加すればいい (see mono site)。

問題になるのは、user32.dllやkernel32.dllなど、Windows上にしか存在しないdllをP/Invokeしている場合だ。Wineにはこれらのライブラリが存在するが、これらはあくまでwineの環境を前提としている。Win32メッセージループのエミュレーションもmonoとwineは独立して行うことになるし、wine上でmono on windowsを動かすなんてのはいびつなやり方だ2

ユーザが自分でwin32 dllに依存しないコードを書くように心がければいいのだけど(FlashDevelopチームなんかは、Monoで動かせるように新バージョンを修正しているという)、誰もがそれをやってくれるとは期待出来ない。

minvokeの解決策は、ユーザによるコードの書き換えはもう期待せずに、必要な範囲でアセンブリを書き換えて、とりあえず実行出来るようにしちゃおう、というものだ。で、これはuser32やkernel32に膨大な関数が含まれていることを考えると、最初から「完成」することは目指していない。でも共通のものは共通のコードで概ね解決できるだろう。いくらでも作業する余地はあるけど、ハッカーが寄ってたかってコードをcontributeできるものでもある。はず。どう進められるか、まだ分からないけれど。

というわけで何か協力してコード書けそうなところがあるという方は協力してやってくらさいw

MIAU勉強会「インターネット標準(RFC)から見た新常用漢字表の矛盾」

遅まきながら明後日おこなわれるMIAUの勉強会の紹介をちらっとだけ書きます。
http://miau.jp/1245391676.phtml

今回は文字コードとRFCその他の技術標準を対象にした、みゃうとしては異色のトピックです。~~本当は先にmonoのUnicode正規化まわりのバグをいくつかやっつけて、.NET実装の出来の悪さをdisりつつその延長で紹介しようと思っていたんだけど、バグフィックスが追いつかなかったというのはおいといて。~~文字コードまわりでは最先端を行っている小形さんが講師です。中の人特権で参加者名簿を見たりしているのですが、ちらほらと詳しい人の名前が見えたりしてウヒヒと思っているというのは秘密です。

個人的には絵文字の方がいろいろと興味のあるところなのですが(NFKD/NFKCの互換文字をどうするとかどの辺の文字を照合順序で同一とみなすかとか)、勉強会自体はそういうトピックでもないですし、既にたいへん細かい記事があるので、それを全部ふまえて話を聞けるところまではいかないかもしんない。Unicodeって麻雀牌とかチェスの駒とか入っていたりするし、甲骨文字の話までしていたりするカオスな標準なんだけど、絵文字ってやっぱりなんか特にflamatoryなんでしょうかね。

というわけで、今回の話題は(絵文字とは全然関係なくて)常用漢字です。常用漢字をめぐる複数の標準がどう整合していないとか、どう整合すればベターなのか、同じような議論がUnicodeやISO/IEC 10646などとの間で問題になっていったりしないか、といった話になると思います。対象が漢字マニヤの集団ではなくみゃうなので、入り口的なところから整理していただけるのではないかと思います。

ともあれ、.NET/WindowsのUnicodeまわりの悪口ならたくさん出てくるわたしも参加します。皆さんもそこはかとなく興味が涌いてきましたら是非おいでくださいませ。まだいっぱいまで埋まっているということはなさそうです。


コメント

atsushieno — 07/01/2009 15:24:02

ありがとうございますー。って金曜だけど大丈夫ですか??<こっちに書くかw

HY — 12/16/2017 23:58:42

user32に対応するクラスを含むアセンブリは、いずれmono本体に入ることになると予測されている。について、現時点ではmonoでuser32は使えるようになっているか教えて欲しい。

atsushieno — 12/17/2017 08:33:53

これ2011年にMonoチームが一度全面的に解体される直前に、いなくなったメンバーがやっていたサイドプロジェクトだからねえ…

HY — 12/22/2017 08:37:56

VisualStudioで作ったプロジェクトを使ってMONOのクロスプラットフォームアプリケーションを作ることはできるか教えて欲しい。

atsushieno — 12/22/2017 10:16:42

んん? 前の質問もそういう次元のものだったのかな。「VisualStudioで作ったプロジェクト」というのはC#のプロジェクトのソースファイルのことかしら。クロスプラットフォームで使えるAPIを使っていれば、VisualStudioで作ってもMonoDevelopとか他のIDEで作っても、アプリケーションはMonoのクロスプラットフォーム環境で実行できる。(まあクロスプラットフォームAPIだけでも、「ファイルI/OのAPIでc:\Windowsにアクセスする」みたいに、Windowsでは動くけどそれ以外では動かないコードも書けちゃう)

HY — 12/24/2017 10:07:58

どのDLLやAPIがクロスプラットフォームで使えるかが明確にわからないんだけど、例えば、MonoDevelopでソースファイルを読み込ませたり、ソースコードを書いたりした場合クロスプラットフォームで使えるコードかどうかを教えてくれる機能とかはあるのか教えて欲しい。

atsushieno — 12/24/2017 12:12:33

どのDLLやAPIがクロスプラットフォームで使えるか

これは答えるのが難しい質問のたぐいだなー。

一般的なXamarin使いの回答を書いてみるよ。

クロスプラットフォームで使えるライブラリとしては、今なら.NET Standard、ちょっと前まだならPCLっていう仕様(PCLのものは大雑把だけど)に沿って作られたものはクロスプラットフォームで使えるんだ。
「MonoDevelopでソースファイルを読み込ませた」ときは、そのプロジェクトの種別でだいたいわかる。コンソールプロジェクトならクロスプラットフォームで動くものが多い(けど、Windows専用のライブラリを参照しているかもしれない)。Windows StoreアプリやUWPのプロジェクトは読み込めない。AndroidやiOSのプロジェクトならクロスプラットフォームじゃあない。PCLや.NET Standardのプロジェクトならたぶん大丈夫だ。

結局、参照されているライブラリがクロスプラットフォームかどうかで決まることが多いと思うけど、.NET Standardに入っているかどうか、が基準としては(この分野においては)とてもわかりやすい部類だ。

ここまでが一般的なXamarin使いで答えそうな内容ね。

MSの連中やXamarinコミュニティの連中はクロスプラットフォームって言った時に.NET FrameworkとかXamarinのことしか考えていないんだけど、たとえばわたしが使っているLinuxデスクトップ上で動作するMonoで使えるかどうか、は、この基準だけだとわからないこともあるんだ。Monoは.NET Framework(デスクトップ)互換環境だけど、Windows依存の機能は大半が動かないし(実はWindows Formsとかもあって、びっくりするくらいコードが動くけど、それでも安心して使えるとは言えない)、でも移植性チェックとかは難しい。プロジェクトのプロファイルはそもそも移植性が無いことになっている.NET Frameworkのものなんだ。まあ、.NET Standardの今ある機能と地道に比較して調べるとかしないと無理そうだ。素人には不可能だよね。

あと、クロスプラットフォームって言ったときに、Unityみたいなのも入ってくると、正直どう答えたらいいのかわからない。Unityのことも視野に入れているなら、ちゃんと調べたほうがいい。

クロスプラットフォームで使えるコードかどうかを教えてくれる機能

使ったことないけど、今はWindows版Visual Studioの拡張で.NET Portability Analyzerっていうツールがあるみたいだ。
https://docs.microsoft.com/en-us/dotnet/standard/portability-analyzer

arton — 12/24/2017 12:23:52

一般的なVisual Studio 2017の利用者の立場で書くと、.NET Core 1.0をプラットフォームにすればLinux(少なくともAWS Lambda)では動いています。

karuakun — 07/01/2009 15:08:20

興味出たー。
ということで申し込みました。

Footnotes

  1. 文字列のマーシャリングなどの扱いが異なる部分はあるけど

  2. wineの箱の中から出られず、ネイティブファイルアクセスやPosixまわりのサポート、さらには将来の世代別GCやデバッグサポートなどさまざまなアドバンテージを失う


この記事を共有:

前の記事
MIAU勉強会「インターネット標準(RFC)から見た新常用漢字表の矛盾」
次の記事
minvoke