ふにゃるんv2

もとは、http://d.hatena.ne.jp/Wacky/

IronPython(.NET)からHyper Estraierを扱う

昨日の続きです〜。
自分は、鉄の○っぱい派でもあるので、IronPythonからも扱ってみようかな?というのが今回のネタです。


今回は、

  • 「ぷろじぇくと、みすじら」版の.NETバイディングをIronPythonから使ってみる
  • SWIG for C#」版の.NETバイディングをIronPythonから使ってみる

の2パターンで行きます。

「ぷろじぇくと、みすじら」版を使ってみる

ここに、専用の.NETバイディングを用意しておられる方が居ますので、それに乗っかりましょう。


HyperEstraierBinding-20070830.zip を展開するとソースとDLLが一緒に入っています。
HyperEstraier.dll を estraier.dll のある場所にコピーして、IronPythonを起動して、以下のように操作してみましょう。

$ cd F:\Wacky\Test\HyperEstraier\hyperestraier-1.4.10-win32\hyperestraier
$ ipy.exe -X:ColorfulConsole -X:AutoIndent -X:TabCompletion
IronPython 2.0 Beta (2.0.0.5000) on .NET 2.0.50727.3053
Type "help", "copyright", "credits" or "license" for more information.
>>> import clr
>>> clr.AddReference("HyperEstraier.dll")
>>> from HyperEstraier import *
>>> db = Database("idx", DatabaseModes.Reader)
>>> cond = Condition()
>>> cond.Phrase = "python"
>>> result = db.Search(cond, None)
>>> for i in range(result.DocumentNumber):
...     doc = db.GetDocument(result.GetDocumentId(i))
...     for attr_name in doc.AttrNames():
...         print "%s : %s" % (attr_name, doc.Attr(attr_name))
...
@author : Mikio Hirabayashi
@digest : f3f401613da4a5b6ee8333fea3bc548f
@id : 3
@lang : en
@size : 8034
@title : Hyper Estraier: a full-text search system for communities
@type : text/html
@uri : file:///F|/Wacky/Test/HyperEstraier/hyperestraier-1.4.10-win32/hyperestra
ier/doc/index.html
_lfile : index.html
_lpath : file:///F|/Wacky/Test/HyperEstraier/hyperestraier-1.4.10-win32/hyperest
raier/doc/index.html
_lreal : F:\Wacky\Test\HyperEstraier\hyperestraier-1.4.10-win32\hyperestraier\do
c\index.html
author : Mikio Hirabayashi
content-language : en
content-script-type : text/javascript
content-style-type : text/css
content-type : text/html; charset=UTF-8
description : homepage of Hyper Estraier
keywords : Hyper Estraier, Estraier, full-text search, API
@author : Mikio Hirabayashi
@digest : 4dd0d5010a97147920eec86045dfda9a
@id : 4
@lang : ja
@size : 13374
@title : 全文検索システム Hyper Estraier
@type : text/html
@uri : file:///F|/Wacky/Test/HyperEstraier/hyperestraier-1.4.10-win32/hyperestra
ier/doc/index.ja.html
_lfile : index.ja.html
_lpath : file:///F|/Wacky/Test/HyperEstraier/hyperestraier-1.4.10-win32/hyperest
raier/doc/index.ja.html
_lreal : F:\Wacky\Test\HyperEstraier\hyperestraier-1.4.10-win32\hyperestraier\do
c\index.ja.html
author : Mikio Hirabayashi
content-language : ja
content-script-type : text/javascript
content-style-type : text/css
content-type : text/html; charset=UTF-8
description : homepage of Hyper Estraier
keywords : Hyper Estraier, Estraier, full-text search, API
>>> dir(doc)
['AddAttr', 'AddHiddenText', 'AddText', 'Attr', 'AttrNames', 'AttributeDictionar
y', 'Attributes', 'CatTexts', 'Dispose', 'DumpDraft', 'Equals', 'GetHashCode', '
GetType', 'Id', 'IsDisposed', 'MakeSnippet', 'MemberwiseClone', 'ReferenceEquals
', 'SetKeywords', 'SetScore', 'Texts', 'ToString', '__class__', '__delattr__', '
__doc__', '__enter__', '__exit__', '__getattribute__', '__hash__', '__init__', '
__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__']
>>>

作者の方のAPI名が少々異なるので(.NETの記名法に従っている)、全く同じという訳には行きませんが、'dir(オブジェクト名)'とすればメソッド/プロパティの一覧が出てくるので、それで補完しながら作業を進めれば、適当にプログラムが出来てしまうでしょう。

SWIG for C#」版を使ってみる

hyper_estraier_wrappers-0.0.15.tar.gz には、SWIG用のインタフェースファイルが用意されています。
で、SWIGには、C#バイディングを出力する機能がありますので、ちゃきちゃき出力してみましょう。

$ cd F:\Wacky\Test\HyperEstraier\hyper_estraier_wrappers-0.0.15
$ swig -c++ -csharp HyperEstraier.i
HyperEstraierWrapper.cpp(16): Warning(401): Nothing known about base class 'std:
:runtime_error'. Ignored.

すると、以下のように C++C# のラッパーファイルが生成されます。(下図の赤囲みしている部分)
1
1 posted by (C)wacky


次に、Visual Studioを起動してソリューションを作り、以下のようにプロジェクトを構成して下さい。

  • HyperEstraierというプロジェクト名で、C++/CLIのDLLプロジェクトを生成し、'HyperEstraier_wrap.cxx'と'HyperEstraierWrapper.cpp'を含める。
    (後で気付いたんですが、もしかしてWin32 DLLでも良いかも知れません。だってC#のP/Invokeの呼出の仕組みがねぇ…)
  • 適当なプロジェクト名で、C#のDLLプロジェクトを生成し、'*.cs'を含める

2
2 posted by (C)wacky


上で出来たファイルが、以下の2ファイルだとします。

  • HyperEstraier.dll : C++/CLIのDLL
  • test2.dll : C#のDLL


これを estraier.dll のある場所にコピーして、IronPythonを起動して、以下のように操作してみましょう。

$ cd F:\Wacky\Test\HyperEstraier\hyperestraier-1.4.10-win32\hyperestraier
$ ipy.exe -X:ColorfulConsole -X:AutoIndent -X:TabCompletion
IronPython 2.0 Beta (2.0.0.5000) on .NET 2.0.50727.3053
Type "help", "copyright", "credits" or "license" for more information.
>>> import clr
>>> clr.AddReference("test2")
>>> import Condition
>>> import Database
>>> import Document
>>> import HyperEstraier
>>> dir()
['Condition', 'Database', 'Document', 'HyperEstraier', '__builtins__', '__doc__'
, '__name__', 'clr']
>>> db = Database()
>>> db.open("idx", Database.DBREADER)
True
>>> cond = Condition()
>>> cond.set_phrase("python")
>>> result = db.search(cond, 0)
>>> dir(result)
['Add', 'AddRange', 'Capacity', 'Clear', 'Contains', 'CopyTo', 'Count', 'Dispose
', 'Equals', 'GetEnumerator', 'GetHashCode', 'GetRange', 'GetType', 'IndexOf', '
Insert', 'InsertRange', 'IntVectorEnumerator', 'IsFixedSize', 'IsReadOnly', 'IsS
ynchronized', 'Item', 'LastIndexOf', 'MemberwiseClone', 'ReferenceEquals', 'Remo
ve', 'RemoveAt', 'RemoveRange', 'Repeat', 'Reverse', 'SetRange', 'ToString', '__
add__', '__class__', '__delattr__', '__doc__', '__enter__', '__exit__', '__getat
tribute__', '__getitem__', '__hash__', '__init__', '__iter__', '__new__', '__red
uce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__str__', 's
wigCMemOwn']
>>> for id in result:
...     doc = db.get_doc(id, 0)
...     for attr_name in doc.attr_names():
...         print "%s : %s" % (attr_name, doc.attr(attr_name))
...
@author : Mikio Hirabayashi
@digest : f3f401613da4a5b6ee8333fea3bc548f
@id : 3
@lang : en
@size : 8034
@title : Hyper Estraier: a full-text search system for communities
@type : text/html
@uri : file:///F|/Wacky/Test/HyperEstraier/hyperestraier-1.4.10-win32/hyperestra
ier/doc/index.html
_lfile : index.html
_lpath : file:///F|/Wacky/Test/HyperEstraier/hyperestraier-1.4.10-win32/hyperest
raier/doc/index.html
_lreal : F:\Wacky\Test\HyperEstraier\hyperestraier-1.4.10-win32\hyperestraier\do
c\index.html
author : Mikio Hirabayashi
content-language : en
content-script-type : text/javascript
content-style-type : text/css
content-type : text/html; charset=UTF-8
description : homepage of Hyper Estraier
keywords : Hyper Estraier, Estraier, full-text search, API
@author : Mikio Hirabayashi
@digest : 4dd0d5010a97147920eec86045dfda9a
@id : 4
@lang : ja
@size : 13374
@title : 蜈ィ譁・、懃エ「繧キ繧ケ繝・Β Hyper Estraier
@type : text/html
@uri : file:///F|/Wacky/Test/HyperEstraier/hyperestraier-1.4.10-win32/hyperestra
ier/doc/index.ja.html
_lfile : index.ja.html
_lpath : file:///F|/Wacky/Test/HyperEstraier/hyperestraier-1.4.10-win32/hyperest
raier/doc/index.ja.html
_lreal : F:\Wacky\Test\HyperEstraier\hyperestraier-1.4.10-win32\hyperestraier\do
c\index.ja.html
author : Mikio Hirabayashi
content-language : ja
content-script-type : text/javascript
content-style-type : text/css
content-type : text/html; charset=UTF-8
description : homepage of Hyper Estraier
keywords : Hyper Estraier, Estraier, full-text search, API
>>>

文字化けしているのが難ですが、前回のコードそのままで、ちゃんと呼べてます。すごいですね。
(文字化けしているのは、バイト列を正しくエンコード処理もせずに表示しているからでしょう。みすじら版のように正しく処理すれば文字化けしないと思います)

まとめ

今回は、以下の2種類の.NETバイディングを試してみました。

  • 「ぷろじぇくと、みすじら」版の.NETバイディングをIronPythonから使ってみる
  • SWIG for C#」版の.NETバイディングをIronPythonから使ってみる

.NETバイディングも結構簡単に動作するものです。
という訳で、将来.NETバイディングもHyper Estraierに標準添付されるかも知れませんね。