掲示板に、次のような質問が掲示板に書かれていたので、ネタにしておく。
IronPythonでのnullは? (投稿者: bucoさん)
はじめまして。
Pythonに触れ始めて時折こちらのサイトをご参考にさせていただいております。
ところで、こういったところにご質問を書くのもすごく恐縮なのですが、文献や参考サイトも少なくどうしても分からないことがあるのでご質問させてください。
IronPythonからC#で作成したdllを呼び出して使用しようとしました。そこで、dllの中に関数の引数にnullを渡したいのですが、渡し方が分りません。PythonではNoneとなっておりますが、C#にNoneを渡すと型が違いますとエラーがでます。
C#のdllの引数にIronPythonからC#でいうnullを渡すことはできないのでしょうか。
ご質問に答えていただければ幸いです。 (April 6, 2009 13:50:58)
IronPythonから C#で作成したdllを呼び出すとき、関数の引数にnullを渡したいということで、None では型が違うとエラーになるので、その場合は、どうしたらよいかということ。ここからは、第六感で答えたわけだけど、
[IronPython] Null pointer passing みたいなことなのかなぁと思ったから、
from System import IntPtr
しておいて、IntPtr.Zero を渡したらどうなるでしょうか?
(April 10, 2009 07:39:48)
たぶん、そういうことなんじゃないかなぁと思って返事をしておいたら、ちゃんと返答があって、
ご返答ありがとうございます。
IntPtr.Zeroを渡すことで無事引数を渡して関数を実行することができました。
ありがとうございます! (April 10, 2009 16:51:39)
ということで、解決したようだ。
IntPtr に関しては、
IntPtr 構造体 や
IntPtr.Zero フィールド のあたり参照。
このフィールドの値は、 null 参照 (Visual Basic では Nothing) と等価ではありません。 IntPtr のインスタンスが 0 以外の値に設定されているかどうかを効率的に確認するにはこのフィールドを使用します。
たとえば、変数 ip が IntPtr のインスタンスであるとします。この変数が設定されているかどうかを確認するには、同変数とコンストラクタから返された値 (たとえば " if ip != new IntPtr(0)... ") を対比します。コンストラクタを呼び出して初期化前の状態のポインタを取得するのは非効率的です。その場合は " if ip != IntPtr.Zero... " または " if !IntPtr.Zero.Equals(ip)... " とコーディングすることをお勧めします。
例えば、
デスクトップ上のすべてのメイン・ウィンドウを列挙するには? みたいな例では、
foreach (Process p in Process.GetProcesses()) {
if (p.MainWindowHandle != IntPtr.Zero) {
Console.WriteLine(p.ProcessName
+ " : " + p.MainWindowTitle);
}
}
のように使われる。new IntPtr(0) としないで、効率化のためにIntPtr.Zero が使えるわけね。
普段 Python のプログラミングだけだと、型を気にすることはないけれど、型が問われるときには、こういうことをしなきゃいけないことも出てくる。
鋼鉄の蛇使いへの道 - IronPythonの復習 (ふにゃるん) のあたりも参照。
>>> import clr
>>> clr.AddReferenceToFile("csextend.dll")
>>> import Simple
>>> from System import IntPtr
>>> Simple.MessageBox(IntPtr(0), "hello IronPython", "hello", 0)
1
ここでは、IntPtr(0) としているけれど、こういう場面でも ItrPtr.Zero を使えばよいかな。
なお、
掲示板 への書き込みは、いつもチェックしているわけではないので、書かれていても気がついていないときもありますので悪しからず。書かれてもスパムが多いので、ときどきざっくり削除してます。加えて、一部の文字列が投稿制限で使えないとか制限がかかってます。なお、この質問に関しても、掲示板の方は、あとで削除しちゃいます。ということでブログのネタにしておくのであった。
IronPythonの世界