Top > OOobbs3 > 98
** [[OOobbs3/98]] [#cd8a000a]
-''サマリ'': OOoBasic から .net framework  は使用できるのでしょうか?
-''環境'': Calc
-''状態'': 未解決
-''投稿者'': [[tabi]]
-''投稿日'': 2012-12-08 (土) 12:34:27

*** 質問 [#r3b0036e]
Excel VBA -> (Libre Office)Calc Basic 移行で試行錯誤中です
Ooo Basicから .net framework(or Java)のクラスライブラリが
使用できたりするのでしょうか?
検索してみても、自分では判断がつかなかったので
NGの場合はpythonで書き直すほうが早いかなと思ったりしている
のですが(WinAPIも使ってたりしているので)
*** 回答 [#e4802c48]
- 利用方法や現在のライブラリの仕様によりますが、 

- コマンドラインから呼び出せる -> OOo Basic は結果を直接取得できないため、ファイル経由になる。Python などでは可。
- .NET ライブラリを declare function できる形式やラッパを書く。(.NET のライブラリを Declare で呼び出せる様にできるかどうか分かりません。)
- Java のライブラリの場合、UNO サービスでラップ、UNO サービスのインスタンス経由で利用。.NET でも利用可能?不明。
-- .NET の場合、最近のバージョン (4 など) が利用できないため、ハックして使えるようにする、もしくはお勧めできません。
- Windows 以外でも使いたい場合、Java であれば大抵問題なし。.NET の場合、Apache OpenOffice では Windows 以外の環境で .NET が利用できないかもしれません。
-- Apache OpenOffice では、最近、Windows 以外の環境でも declare function でダイナミックリンクライブラリから関数を呼び出すパッチが投稿されていました。

-- はにゃ? &new{2012-12-08 (土) 21:53:09};
- UNO サービスでラップ、UNO サービスのインスタンス経由で利用<ポインター等教えていただけないでしょうか? -- tabi &new{2012-12-10 (月) 09:58:25};
- UNO サービスでラップするのは、新しいサービスを作成、拡張機能としてインストールできるようにすることになります。手順の概要は以下のような感じですが、Java で作成するのであれば Netbeans や Eclipse 用のプラグインを利用するといいかもしれません (私は使ったことがありませんが・・・)。

Netbeans 用のプラグインを利用して、独自のインターフェースを定義している簡単な例があります。
[[http://wiki.openoffice.org/wiki/General_UNO_Component_Project_Type]]

ページの最後にあるように、Java で記述、作成したサービスを OOo Basic の CreateUnoService ランタイム関数でインスタンス化、そのサービスが提供しているインターフェースからメソッドを呼び出しています。

-- UNO コンポーネントを記述できる言語を選択 (その言語用の implementation loader が必要)。デフォルトでは、C++、Java
、Python のうちから選択します。C# は LibreOffice のみでサポートされているかもしれません。
-- SDK をインストールしておく。このうち、IDL ファイルや IDLC が必要です。
-- 自分のサービスの IDL を書く。(UNO) IDL で API を定義します。Java の IDE 用のプラグインを使ったり、API リファレンスと SDK に含まれている IDL ファイルを比較すれば書き方は分かると思います。
-- cppumaker や javamaker でヘッダやクラスファイルを生成。Python では不要 (配布するライブラリをC++ や Java から利用できる様にするには必要ですが、IDL を同梱しておけばよいかも)。
-- 必要に応じて、uno-skeletonmaker で UNO サービスを実装するクラスの外形 (メソッドの外側など) を作成。全部手書きする場合やプラグインを利用している場合は不要。
-- メソッドの中身を記述。注意する必要があるのは型マッピングなど [[http://d.hatena.ne.jp/hanya_orz/20091210/p1]]
--- 既存のクラスをラップする場合、そのクラスのインスタンスをどのように利用するかは、そのクラスに依存します。たとえば、メソッド内でインスタンス化して使い捨てられる場合、サービスがインスタンス化されたときにそのクラスのインスタンスも作成しておく場合、特殊な場合では singleton としてインスタンス化する場合もあるかもしれません (UNO サービスの代わりに singleton を定義できます)。
-- コンパイルなどを行う。手作業で行う場合、C++ なら SDK 付属のヘッダファイル、Java ならいくつかの jar ファイルが必要。
-- 拡張機能としてパッケージング。(拡張機能としてではなく、サービスを実装したファイルを直接型情報ファイルに書き込む方法もありますが、現在はこの方法を使うべきではありません。拡張機能をインストールするとこれと同じことを行なってくれます。)
-- 拡張機能をインストール。
-- コードや UI などから利用。

長々とわかりにくいですが、各言語用に、サービスを実装したファイルを読み込んでロードする implementation loader が必要です (実態は UNO サービスなので自作可)。サービスのインスタンス化の経路はローダーの実装によって異なります。[[http://wiki.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Professional_UNO]] 参照。

-- はにゃ? &new{2012-12-10 (月) 11:28:33};
- C++ でラップして独自のサービスを作成した例を挙げておきます。[[https://github.com/hanya/MTRandom]]
この場合、C++ で書かれた既存の Mersenne Twister 擬似乱数発生器を UNO サービス経由で利用できるようにしています。サービスを三つ定義 (追加という意味で) していますが、Basic などから呼び出せるもの、表計算シート上で関数として呼び出せる形式、3つ目はオプション設定用です。

Basic などから呼び出せるものについて簡単に説明します。シート関数は Add-In と呼ばれるだけで、実装の仕方は同じです。
- [[https://github.com/hanya/MTRandom/blob/master/idl/mytools/math/MTRandom.idl]] サービスの定義です。サービスには旧タイプと新タイプがあります。
-- 旧タイプ: IDL 定義はなくてもよい。ヘッダファイルなどが生成されない。他の人がそのサービスに準じたものを作成する場合や、プロパティ、インターフェースのサポート情報など、単純にリファレンス用。
-- 新タイプ: IDL でコンストラクタを定義でき、他は旧タイプと同じ。(実装に依存するが、) コンストラクタの呼び出しはインスタンス化時の初期化パラメータの型チェックやその情報のため。例えば、C++ のヘッダファイルを生成すると、コンストラクタの中身は自動的に生成され、createInstanceWithArguments メソッドの初期化用の引数の中身を any 型から抽出 (型変換やチェックを含む) するだけ。
- サービスが継承しているインターフェース [[https://github.com/hanya/MTRandom/blob/master/idl/mytools/math/XMTRandom.idl]]
-- ここで定義されているメソッドは UNO サービスのインスタンスから (利用する言語バインディングに依存した方法で) 呼び出せます。
- IDL から cppumaker で生成したファイルはレポジトリにありませんが、そのファイルをインクルード、その中に定義されているクラスを継承したサービスをクラスとして定義します。 [[https://github.com/hanya/MTRandom/blob/master/src/mt.hpp]] 
- 各メソッドの定義 [[https://github.com/hanya/MTRandom/blob/master/src/mt.cpp]]
- 定義したクラスをサービスとして公開、要するに C++ 用の implementation ローダーがクラスのインスタンス化を要求できるように、追加のコードが必要です。[[https://github.com/hanya/MTRandom/blob/master/src/mt_service.cpp]] これはローダーに依存します。
- コンパイルして dll や so ファイルを作成、ローダーは component_XXX といった関数を動的にリンクします。以前は component_writeInfo 関数が実装に関する情報を書きこんでいましたが、最近のバージョン (AOO 3.4、LO 3.5?) では方式が変更されました。コンパイル済みパッケージに含まれている libs/XXX.components ファイルを参照してください。(現在の方法は passive registration と呼ばれ、古い方法は active registration と呼ばれます。)
- 拡張機能パッケージに入れてあり、インストール時に処理してほしいものは META-INF/manifest.xml ファイルに記載が必要です。XXX.components ファイルの指定が必要です。active の場合はここで dll や so ファイルを指定していましたが、passive になってからは xxx.components ファイルを指定します (拡張子は特に重要でない・・はず)。

-- はにゃ? &new{2012-12-10 (月) 12:17:43};
- 開発中やテストについて。
-- Java の IDE 用プラグインではテスト時に拡張機能をインストールしてくれる場合もありますが、問題が起きることがあるようです (使っていないので合ったことはありませんが、フォーラムなどで質問を見かけることがあります)。
-- そこで、拡張機能パッケージを一度インストールすると生成されるプロファイル中のディレクトリを調べておき、dll, so, jar ファイルを置き換えると便利だったりします (Python なら py ファイル)。ローダーはそれらのファイルを読み込んだ後はキャッシュするので、OOo を再起動する必要があります。

-- デバッグは、Java ならリモートデバッグ。C++ で Linux 環境なら GDB が使えますし、Windows であれば VC++ のデバッグ用ツールが使えるようです (Windows でデバッグしたことがないのですが、dev@ ではそんな感じです)。

-- はにゃ? &new{2012-12-10 (月) 14:42:04};

#comment
*** 感想,コメント,メモ [#nd4196b1]

#comment

Reload   New Lower page making Edit Freeze Diff Upload Copy Rename   Front page List of pages Search Recent changes Backup   Help   RSS of recent changes