2017年5月6日土曜日

13: UNOの基本概念を学ぼう、パート4

<このシリーズの、前の記事 | このシリーズの目次 | このシリーズの、次の記事>

Main body START

UNOプロキシは、メソッドの戻りタイプUNOインターフェースに対して作られる

-Hypothesizer

UNOプロキシが何かを既に学んだが、意識しておかないといけないことが一つある。

-Rebutter

ははあ。

-Hypothesizer

UNOプロキシは、メソッドの戻りタイプUNOインターフェースに対して作られる。

-Rebutter

. . . よく理解できない。どのメソッドのことを言っているのか?

-Hypothesizer

例をとって考えてみよう。あるプログラミング言語環境、PLE-A、があり、あるUNOオブジェクト、UO-A-A0、がPLE-A内に生きている。別のプログラミング言語環境、PLE-B、があり、我々は、PLE-Bからブリッジを通してUO-A-A0を操作する。UO-A-A0には、あるUNOオブジェクト、UO-A-A、を生成して戻すメソッドがある。

-Rebutter

オーケー。

-Hypothesizer

このメソッドの戻りタイプは、あるUNOインターフェース、UI-Z、として指定されている。

-Rebutter

分かった。

-Hypothesizer

PLE-Bからこのメソッドを呼ぶ時、ブリッジは、この戻り操作を伝播し、あるUNOプロキシ、UP-B-A-UI-Z、が生成され、我々に戻される。このプロキシ、UP-B-A-UI-Z、は、UNOインターフェース、UI-Z、のみを代表している。つまり、このプロキシは、UI-Zのメソッドのみを持っている。

-Rebutter

すると、このUNOオブジェクト、UO-A-A、が別のUNOインターフェース、UI-Y、を実装していても、我々は、我々のUNOプロキシ、UP-B-A-UI-Z、でUI-Yのメソッドを呼べないということになる。. . . UI-Yのメソッドを呼びたいとしたらどうする?

-Hypothesizer

ユーティリティクラスのメソッド、'com.sun.star.uno.UnoRuntime.queryInterface'があり、我々が既に持っているUNOプロキシを受け取り、我々が望むUNOインターフェースのUNOプロキシを返してくれる。もちろん、元のUNOオブジェクトが、そのUNOインターフェースを実装していればの話だが。

-Rebutter

ほう。

-Hypothesizer

ちなみに、この件に関して、参考文書の'First UNO'部分の説明は、私には理解できない。それによると、メソッドの戻りを別のUNOインターフェースタイプにキャストできない(先に述べたケースでは、UI-ZからUI-Y)のは、戻されたオブジェクトがそのUNOインターフェース(先に述べたケースでは、UI-Y)のオブジェクトだとコンパイラーが知らないからだとされている。

-Rebutter

はあ?それは、妙だ。Javaでは、我々がオブジェクトをあるタイプにキャストするのは、そのオブジェクトがそのタイプのオブジェクトであることをコンパイラーが知らいないからだ。それが、Javaにおけるタイプキャストの概念だ。もし、コンパイラーがそれを知っているのであれば、タイプキャストによって、それをコンパイラーに教える必要はない。Javaコンパイラーは、そのオブジェクトがそのタイプのオブジェクトだと既に知っているのにタイプキャストを要求するほと頭が悪くも不親切でもない。

-Hypothesizer

参考文書の説明がどういう意味なのか理解しようとして、ずいぶん時間を無駄にしてしまった。

-Rebutter

. . . 私が見る限り、説明がそうなっているのは、著者が、プロキシの概念を導入せずに説明しようとしたからのように思われる。著者は我々よりUNOについてはるかによく知っているものと思われるが、その説明は混乱を生むものだ。プロキシの概念は読者を混乱させると著者は考えたのかもしれないが、不正確な記述は読者をもっと混乱させる。

-Hypothesizer

教訓として、その場を取り繕ろうために物事を不正確に記述することは、我々はしないように気をつける必要がある。

ところで、これは、特に推奨するわけではないが、実際には、メソッドの呼び出しがブリッジ経由でない場合は、戻りオブジェクトをUNOインターフェースに直接キャストすることができる。そのケースでは、戻されたオブジェクトはUNOプロキシではなくUNOオブジェクトそのものであって、したがって、それを、そのUNOオブジェクトが実装しているUNOインターフェースタイプに直接キャストすることができる。

-Rebutter

メカニズムを正確に理解していれば、それが自然な結論だ。

UNOIDL(UNO Interface Definition Language)とは何か?UNOデータタイプレジストリとは何か?

-Hypothesizer

UNOはプログラミング言語に独立なので、UNOインターフェースなどのUNOデータタイプは、UNOをサポートするすべてのプログラミング言語によって認識されないといけない。そのため、我々は、UNOデータタイプを、プログラミング言語に独立な形態で登録する必要がある。そうしたUNOデータタイプを格納するレジストリが、UNOデータタイプレジストリだ。

-Rebutter

ふーむ、その説明は、一見するともっともらしいが、実際には説得力がない。C++環境に生存するUNOオブジェクトにJava環境からアクセスする時、我々は、JavaインターフェースとしてのUNOインターフェースを必要とする。さもなければ、我々は、Javaプログラムをコンパイルすることすらできない。UNOデータタイプをJavaインターフェースによって認識できるのに、プログラミング言語に独立な形態のUNOデータタイプが必要だろうか?

-Hypothesizer

うーん、正直なところ、私には分からない。我々はUNO拡張機能をC++で開発しないので、今のところ、それをテストすることができない。しかし、少なくとも、LibreOffice Basicマクロは、それを必要としそうだ。

-Rebutter

プログラミング言語に独立な形態でUNOデータタイプを登録して何も害がないのはわかるが、メカニズムが不明確だと私は落ち着かない。C++のUNO拡張機能を作ってテストしないか、そのうちに?

-Hypothesizer

オーケー。そのうちにね。

とにかく、我々は、UNOデータタイプを、UNOIDLというUNO独自の定義言語で定義し、UNOIDLのソースファイルをUNOデータタイプ「マージされていない」レジストリファイルにコンパイルし、複数のそうしたファイルをマージして、UNOデータタイプ「マージされた」レジストリファイルを作る。このUNOデータタイプ「マージされた」レジストリファイルを使用して、我々のUNOデータタイプをLibreOfficeのUNOデータタイプレジストリに登録することができる。

-Rebutter

UNOデータタイプ「マージされた」レジストリファイルを具体的にどのように使用することができるのか?

-Hypothesizer

UNO拡張機能にこのファイルを含めて、UNO拡張機能マネージャーにUNOデータタイプを登録させることができるし、このファイルそのものをUNOデータタイプレジストリに登録することもできる。我々のサンプルUNO拡張機能では、前者を行なった。将来の記事では。後者を行なうつもりだ。

ところで、JavaインターフェースとしてのUNOインターフェースは、UNOのツールを使って、UNOデータタイプ「マージされた」レジストリファイルから生成することができる。したがって、JavaインターフェースとしてのUNOインターフェースのJavaソースファイルを我々が書く必要はない。

-Rebutter

なるほど。

Main body END

References

  • Apache OpenOffice Wiki. (2014/01/02). Apache OpenOffice Developer's Guide. Retrieved from https://wiki.openoffice.org/wiki/Documentation/DevGuide/OpenOffice.org_Developers_Guide

<このシリーズの、前の記事 | このシリーズの目次 | このシリーズの、次の記事>