2020年10月18日日曜日

44: C++で任意のUNOコンポーネントを定義する

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

典型的にはリスナーを作成するために。UNOガーベッジコレクション、ウィークポインティング、等の知識が必須でありここにあります。

話題


About: UNO (Universal Network Objects)
About: LibreOffice
About: Apache OpenOffice
About: C++

この記事の目次


開始コンテキスト



ターゲットコンテキスト



  • 読者は、C++で任意のUNOコンポーネントを定義する方法を知る。
ト書き
Hypothesizer 7、Objector 44A、Objector 44Bがコンピューターの前にいる。


オリエンテーション


Hypothesizer 7
本記事では、C++で任意のUNOコンポーネント定義する方法を知ります。

'UNOコンポーネント'で私が何を意味しているかを正確に理解しておいてください。実のところ、私は'::com::sun::star::lang::XComponent'実装だけを意味しているわけではありません、勿論、どの'::com::sun::star::lang::XComponent'実装も一種のUNOコンポーネントではありますが。

Objector 44A
はあ?それは禅の公案か?

Hypothesizer 7
サー、'XComponent'のネーミングは. . .的を得ていません、私の意見では: '::com::sun::star::lang::XComponent'の実際の意味は、'恣意的に廃棄可能である'であり、それは、全然、一般的なコンセプトとしてのコンポーネントであることの必要な特徴ではありません。その名前は、'XArbitrarilyDisposable'のようであるべきだった、と私は考えます。.

Objector 44A
不細工な名前だな!

Hypothesizer 7
その名前が、そのUNOインターフェイスの本当の意味を最も正確に表わしているようです. . .

Objector 44A
少なくとも、'XDisposable'にしろ、そのほうがかっこいい。

Hypothesizer 7
実のところ、「Arbitrarily」という部分が、意味の要旨を表わしているのです。実際、かっこいいことが正確であることに優先するような価値体系を私は有していません。

Objector 44A
そもそも、「恣意的に廃棄可能である」が何を意味するのか、私には分からん。

Hypothesizer 7
あるセクションでご理解されるでしょう。

Objector 44B
そもそも、なぜ自分でUNOコンポーネントを定義しないといけないのかが分からないのよね。LibreOffice内にある、既存のUNOコンポーネントをいくつか使うだけでしょ?

Hypothesizer 7
マダム、典型的には、リスナーを作成されたい場合に、UNOコンポーネントを定義される必要があります。

Objector 44B
「リスナー」?

Hypothesizer 7
例えば、あるUNOディスパッチコマンド実行から全情報を取得されたい時、その情報を知らされる1つまたは複数のリスナーを作成されます。

Objector 44B
だから何?

Hypothesizer 7
そうしたリスナーたちの各クラスは、UNOコンポーネントでなければなりません。

Objector 44B
. . .UNOディスパッチ実行のため以外の使用法なんて思いつかないけど。

Hypothesizer 7
つかれませんか?実際には、他の多くのイベント群をリッスンすることができます、例えば、ドキュメントのオープン、ドキュメントのクローズ、、キー入力、マウスクリック、スプレッドシートセルの選択変更、オフィスインスタンスの停止試行、等。

Objector 44B
. . .どっちみち、リスナーだけの問題でしょ?

Hypothesizer 7
そういうわけでもありません。私は、UNOオブジェクト群コンテキストクラスを作成しました。いくつかのUNOサービスを以降のいくつかの記事で作成するでしょう。

Objector 44B
それらはUNOコンポーネントとどう関係してるわけ?

Hypothesizer 7
UNOオブジェクト群コンテキストクラスは、必然的にUNOコンポーネントです。UNOサービスとは、荒く言って、登録されたUNOコンポーネントのことです。


本体


1: C++ UNOのガーベッジコレクションメカニズムを理解する


Hypothesizer 7
最初に、C++ UNOのガーベッジコレクションメカニズムを理解しましょう。

Objector 44A
はあ?UNOコンポーネントを具体的にどう作成するかをただ教えろよ、馬鹿げた講釈なしに!

Hypothesizer 7
. . .それを馬鹿げているとは私は見なしません。必要なイントロダクションです。

Objector 44A
ああそうかい. . .

Hypothesizer 7
UNOがサポートされている、Javaのような他のプログラミング言語群のそれぞれはそれ自身のビルトインガーベッジコレクションメカニズムを持っていますが、C++は違います。

Objector 44A
知ってるよ. . .

Hypothesizer 7
そこで、C++ UNOは、あるガーベッジコレクションメカニズムを実装し、そのために、あなたは、各ローカルUNOオブジェクトUNOプロキシの使用カウントをインクリメントおよびデクリメントしなければなりません。

Objector 44A
「UNOプロキシ」?

Hypothesizer 7
リモートUNOオブジェクトを操作される際、あなたは、そのリモートUNOオブジェクトを直接に操作するのではなく、直接にはいくつかのUNOプロキシを操作されますが、それらは、適切にガーベッジコレクトされなければなりません。実際、リモートUNOオブジェクト自体のガーベッジコレクションを心配される必要はありませんが、それは、UNOブリッジが面倒を見るからであり、それには、UNOプロキシ群が適切にガーベッジコレクトされることが必須です。

Objector 44A
分かった。

Hypothesizer 7
UNOオブジェクトまたはUNOプロキシの使用カウントが'0'へと減少した時、そのUNOオブジェクトまたはUNOプロキシは廃棄されます。

Objector 44A
それじゃあ、使用カウントというのは、そのUNOオブジェクトまたはUNOプロキシへのポインターの数なんだな?

Hypothesizer 7
そう推測しますが、厳密な数字は、実際上は、どうでも構いません、なぜなら、実際上問題なのは、それが'0'になるタイミングだけだからです。

Objector 44A
それじゃあ、もしも、消滅地点が明らかだった、ただ、最初に'1'へインクリメントし、最後に'0'へデクリメントすればよいと、中間の面倒なインクリメントとデクリメントは全てスキップして?

Hypothesizer 7
実際上の話は、そうです。


2: '::com::sun::star::uno::Reference'および'::com::sun::star::uno::WeakReference'というデータタイプの意義を理解する


Hypothesizer 7
使用カウントを明示的にインクリメント・デクリメントするのは面倒だから、任意のUNOオブジェクトまたはUNOプロキシのアドレスのラッパーがあり、それが、'::com::sun::star::uno::Reference'です。

アドレスが'::com::sun::star::uno::Reference'データへセットされる時、使用カウントが自動的にインクリメントされ、アドレスが'::com::sun::star::uno::Reference'データから解除される時(それは、'::com::sun::star::uno::Reference'データが廃棄される時にも自動的に起こる)、使用カウントが自動的にデクリメントされます。

Objector 44A
そんなの必要ないよ、だって、面倒なインクリメント・デクリメントを全てスキップする戦略を私は採るから。

Hypothesizer 7
ところが、おそらくは、あなたはそれを使わなければなりません、なぜなら、UNO API中のメソッドの引数またはリターンのUNOインターフェイスタイプは、C++では、全て、'::com::sun::star::uno::Reference'タイプへマップされているからです。

Objector 44A
はあ?

Hypothesizer 7
例えば、'::com::sun::star::lang::XComponent'の'void addEventListener ([in] ::com::sun::star::lang::XEventListener xListener)'は、C++では、'void addEventListener (::com::sun::star::uno::Reference <::com::sun::star::lang::XEventListener> const & xListener)'へマップされています。

Objector 44A
じゃあ、'::com::sun::star::uno::Reference'を使わよう強制されているわけか. . .

Hypothesizer 7
他方では、'::com::sun::star::uno::WeakReference'もあり、それは、使用を連続的に要求することはしません。

Objector 44A
「連続的に要求する」?

Hypothesizer 7
そこでの'要求する'は、使用カウントをインクリメントし、使用カウントを即座にデクリメントしないことを意味します。

Objector 44A
はあ?

Hypothesizer 7
'::com::sun::star::uno::WeakReference'は、ポイントされているUNOオブジェクトを実際にアクセスする直前に使用カウントをインクリメントし、アクセスが完了した直後に使用カウントをデクリメントします。

Objector 44A
それで、それは. . .何のために役に立つのだ?

Hypothesizer 7
えーと、私の理解によれば、'::com::sun::star::uno::Reference'は、オーナーとしてポイントすることを表わしており、'::com::sun::star::uno::WeakReference'は、ユーザーとしてポイントすることを表わしています。オーナー(実際には、複数のオーナーがいるかもしれない)が、当該UNOオブジェクトがいつ廃棄されるべきかを決定する一方、ユーザーたちは、当該UNOオブジェクトの生存期間を決定せず、当該UNOオブジェクトを、それがもしもまだ存在するのであれば使用するというだけです。. . .'::com::sun::star::uno::WeakReference'は、そうしたデータ構造を確立するのに役に立ちます。

オフィシャルドキュメントはサイクリックポインティングを避けることについて述べていますが、それは単に1つのケースにすぎません(もしもそれが典型例だとしても)、私の意見では。

Objector 44A
ああ。

Hypothesizer 7
いずれにせよ、UNOオブジェクトが弱くポイントされるためには、当該UNOコンポーネントは、'::com::sun::star::uno::XWeak'というUNOインターフェイスを実装しておかなければなりません。.

'::com::sun::star::uno::XWeak'は単一のメソッド、'com::sun::star::uno::XAdapter queryAdapter ()'を持っており、それは、当該UNOオブジェクトのためのアダプターをリターンしますが、ここで、'アダプター'は、'::com::sun::star::uno::WeakReference'インスタンスがポイントする代理UNOオブジェクトを意味します、元のUNOオブジェクトをグリップしないために。 .

Objector 44A
えーと、私のどのUNOコンポーネントにもそれを実装させたほうがよさそうだな。


3: '::com::sun::star::lang::XComponent'の意味を理解する


Hypothesizer 7
'::com::sun::star::lang::XComponent'の意味は、その名前が虚偽に主張するような、コンポーネントであることではなく、恣意的に廃棄可能であることです。

Objector 44A
「恣意的に廃棄可能である」というのが何を意味するのか、私には理解できん。

Hypothesizer 7
当該ガーベッジコレクションメカニズムによれば、通常は、UNOオブジェクトは恣意的に廃棄することはできません、なぜなら、もしもそうであったら、そのUNOオブジェクトへのポインターは、その後に、その今や存在しないUNOオブジェクトにアクセスして使用カウントをデクリメントしようとして(なぜなら、そうしないといけないから)、セグメンテーションフォールト(多分)を起こすからです。

Objector 44A
ああ、そのガーベッジコレクションメカニズムの統制下においては、UNOオブジェクトを明示的に廃棄する必要がないだけではなくて、UNOオブジェクトを明示的に廃棄することが許されていないのだ。UNOオブジェクトは、そのガーベッジコレクションメカニズムによって廃棄されなければならないのだ。

Hypothesizer 7
もしも、あるUNOオブジェクトが恣意的に廃棄されなければならないのであれば、それは、それへのすべてのポインターに通知しなければならないでしょう、それらのポインターはそのUNOオブジェクトを即座にリリースしなければならないと。

'::com::sun::star::lang::XComponent'は3個のメソッド、'void addEventListener ([in] XEventListener xListener)'、'void removeEventListener ([in] XEventListener aListener)'、'void dispose ()'を持っており、前2メソッドは、ポインター群のマネージャー群を登録・登録解除するためのものであり、最後のメソッドは、自らを廃棄する前に、ポインター群のマネージャー群に通知するためのものです。


4: 任意のUNOコンポーネントにとっての、4個のオプション


Hypothesizer 7
上記の考察に沿って、任意のUNOコンポーネントにとって、4個のオプションがあります: 1) 弱くポイントされることができず、恣意的に廃棄することができない、2) 弱くポイントされることができ、恣意的に廃棄することができない、3) 弱くポイントされることができず、恣意的に廃棄することができる、4) 弱くポイントされることができ、恣意的に廃棄することができる。


5: さあ、UNOコンポーネントを作ろう


Hypothesizer 7
どのUNOコンポーネントも、'::com::sun::star::uno::XInterface'を実装しなければなりませんが、それは、3個の必須メソッド、'void acquire ()'、'void release ()'、'any queryInterface ([in] type aType)'を持っています。

前2メソッドは、使用カウントをインクリメントおよびデクリメントして当該UNOオブジェクトを適切に廃棄するためのものです。

UNO APIドキュメント中の'queryInterface ([in] type aType)'の記述は、. . .、なんと申しましょうか、. . .破綻しています、私の意見では: "a interface reference of the requested type(リクエストされたタイプのインターフェイスリファレンス)"とはどういう意味でしょうか?「a interface reference(インターフェイスリファレンス)」?. . .もしも、"リファレンス"という用語のそのような使用法への不満を仮に脇に置いて、「リファレンス」を'アドレス'と解釈するとしても、その記述は意味をなしていません: 「interface address(インターフェイスアドレス)」は'インターフェイスのアドレス'のように聞こえますが、C++にはそのようなものは存在しませんよね?. . .Javaにおいては、'Xinterface.class'はそのインターフェイスのアドレスを表わしていますが、C++では?. . .「obtain other interfaces(他のインターフェイスを取得する)」のような記述も意味をなしません: C++では、インターフェイス自体など取得できないでしょう?. . .

実際には、そのメソッドは、当該UNOオブジェクトのアドレスが'::com::sun::star::uno::Reference <%指定されたUNOインターフェイス%>'でラップされて、'::com::sun::star::uno::Any'にラップされたものをリターンします、C++的には。

Objector 44A
「C++的には」?

Hypothesizer 7
実際には、そのメソッドは、C++においてのみ存在します、私が知る限りでは(少なくとも、Javaには存在しません)。

Objector 44A
ふーむ。

Hypothesizer 7
そして、通常、UNOコンポーネントは、'::com::sun::star::lang::XTypeProvider'も実装しますが、それは、2個のメソッド、'sequence <type> getTypes ()'および'sequence <byte> getImplementationId ()'を持っています。

Objector 44A
「通常」?

Hypothesizer 7
そのUNOコンポーネントがもしも、LibreOfficeまたはApache OpenOffice Basicのようなスクリプト言語から使われることがないのであれば、それは、必須ではありません。

Objector 44A
ああ。

Hypothesizer 7
前者メソッドは、実装されたUNOインターフェイス群のタイプデータのシーケンスをリターンします、C++的には、'::com::sun::star::uno::Sequence <::com::sun::star::uno::Type>'です。

後者メソッドは、使用非推奨になっています。

Objector 44A
ああ。

Hypothesizer 7
そうしたメソッド群をご自分で実装されることも、その気があれば可能ですが、多分、それらを実装済みの、以下の3個のヘルパークラステンプレート群グループに分類される、あるクラステンプレートをご使用になるでしょう: '::cppu::ImplHelper%追加されるUNOインターフェイスの数%'、'::cppu::WeakImplHelper%追加されるUNOインターフェイスの数%'、'::cppu::WeakComponentImplHelper%追加されるUNOインターフェイスの数%'、ここで、%追加されるUNOインターフェイスの数%というのは、明示的に実装なさりたいUNOインターフェイスの数を意味します。

Objector 44A
「明示的に」?

Hypothesizer 7
つまり、ヘルパー自身によって実装されないUNOインターフェイス群のことです。

Objector 44A
分かった。

Hypothesizer 7
前セクションにおけるオプション1に対しては、'::cppu::ImplHelper%追加されるUNOインターフェイスの数%'を使用できますが、それは、'queryInterface ([in] type aType)'および'::com::sun::star::lang::XTypeProvider'の全体を実装済みですが、'acquire ()'および'release ()'を実装していないものです。 .

以下は、使用例です。

theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/Option1UnoComponent.hpp

@C++ ソースコード
#ifndef __theBiasPlanet_unoUtilitiesTests_localUnoObjectsTest1_Option1UnoComponent_hpp__
#define __theBiasPlanet_unoUtilitiesTests_localUnoObjectsTest1_Option1UnoComponent_hpp__
	#include <cppuhelper/compbase1.hxx>
	#include <com/sun/star/lang/XUnoTunnel.hpp>
	#include <com/sun/star/uno/Sequence.hxx>
	
	using namespace ::std;
	using namespace ::com::sun::star::lang;
	using namespace ::com::sun::star::uno;
	using namespace ::cppu;
	
	namespace theBiasPlanet {
		namespace unoUtilitiesTests {
			namespace localUnoObjectsTest1 {
				class Option1UnoComponent: public ImplHelper1 <XUnoTunnel> {
					private:
						int i_usageCount = 0;
					public:
						Option1UnoComponent ();
						virtual ~Option1UnoComponent ();
						virtual void SAL_CALL acquire () override;
						virtual void SAL_CALL release () override;
						virtual sal_Int64 SAL_CALL getSomething (Sequence <sal_Int8> const & a_datumIdentification) override;
				};
			}
		}
	}
#endif


theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/Option1UnoComponent.cpp

@C++ ソースコード
#include "theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/Option1UnoComponent.hpp"
#include <iostream>

namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace localUnoObjectsTest1 {
			Option1UnoComponent::Option1UnoComponent (): ImplHelper1 <XUnoTunnel> () {
				cout << "### 'Option1UnoComponent::Option1UnoComponent ()' is called." << endl << flush;
			}
			
			Option1UnoComponent::~Option1UnoComponent () {
				cout << "### 'Option1UnoComponent::~Option1UnoComponent ()' is called." << endl << flush;
			}
			
			void SAL_CALL Option1UnoComponent::acquire () {
				cout << "### 'Option1UnoComponent::acquire ()' is called." << endl << flush;
				i_usageCount ++;
			}
			
			void SAL_CALL Option1UnoComponent::release () {
				cout << "### 'Option1UnoComponent::release ()' is called." << endl << flush;
				i_usageCount --;
				if (i_usageCount <= 0) {
					delete this;
				}
			}
			
			sal_Int64 SAL_CALL Option1UnoComponent::getSomething (Sequence <sal_Int8> const & a_datumIdentification) {
				return (sal_Int64) this;
			}
		}
	}
}


Objector 44A
「::com::sun::star::lang::XUnoTunnel」?

Hypothesizer 7
それは、ここでのポイントではありません: 私がそれを使用したのは、ただ、少なくとも1つの追加UNOインターフェイスを指定しなければならないからにすぎません。.

Objector 44A
ふーむ、それら2つのメソッドも実装していて欲しかったのだが. . .

Hypothesizer 7
前セクションのオプション2に対しては、'::cppu::WeakImplHelper%追加されるUNOインターフェイスの数%'を使用できますが、それは、'XInterface'の全体、'::com::sun::star::lang::XTypeProvider'の全体、'::com::sun::star::uno::XWeak'の全体を実装済みのものです。

以下は、使用例です。

theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/Option2UnoComponent.hpp

@C++ ソースコード
#ifndef __theBiasPlanet_unoUtilitiesTests_localUnoObjectsTest1_Option2UnoComponent_hpp__
#define __theBiasPlanet_unoUtilitiesTests_localUnoObjectsTest1_Option2UnoComponent_hpp__
	#include <cppuhelper/compbase1.hxx>
	#include <com/sun/star/lang/XUnoTunnel.hpp>
	#include <com/sun/star/uno/Sequence.hxx>
	
	using namespace ::std;
	using namespace ::com::sun::star::lang;
	using namespace ::com::sun::star::uno;
	using namespace ::cppu;
	
	namespace theBiasPlanet {
		namespace unoUtilitiesTests {
			namespace localUnoObjectsTest1 {
				class Option2UnoComponent: public WeakImplHelper1 <XUnoTunnel> {
					public:
						Option2UnoComponent ();
						virtual ~Option2UnoComponent ();
						virtual sal_Int64 SAL_CALL getSomething (Sequence <sal_Int8> const & a_datumIdentification) override;
				};
			}
		}
	}
#endif


theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/Option2UnoComponent.cpp

@C++ ソースコード
#include "theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/Option2UnoComponent.hpp"
#include <iostream>

namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace localUnoObjectsTest1 {
			Option2UnoComponent::Option2UnoComponent () : WeakImplHelper1 <XUnoTunnel> () {
				cout << "### 'Option2UnoComponent::Option2UnoComponent ()' is called." << endl << flush;
			}
			
			Option2UnoComponent::~Option2UnoComponent () {
				cout << "### 'Option2UnoComponent::~Option2UnoComponent ()' is called." << endl << flush;
			}
			
			sal_Int64 SAL_CALL Option2UnoComponent::getSomething (Sequence <sal_Int8> const & a_datumIdentification) {
				return (sal_Int64) this;
			}
		}
	}
}


Objector 44A
よさそうだな。それが、私の通常の選択になる、多分。

Hypothesizer 7
前セクションのオプション3に対しては、前述の'::cppu::ImplHelper%追加されるUNOインターフェイスの数%'を使用して、'XComponent'を追加UNOインターフェイスとして追加しなければならないでしょう。

以下は、使用例です。

theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/Option3UnoComponent.hpp

@C++ ソースコード
#ifndef __theBiasPlanet_unoUtilitiesTests_localUnoObjectsTest1_Option3UnoComponent_hpp__
#define __theBiasPlanet_unoUtilitiesTests_localUnoObjectsTest1_Option3UnoComponent_hpp__
	#include <set>
	#include <com/sun/star/lang/XComponent.hpp>
	#include <com/sun/star/lang/XEventListener.hpp>
	#include <com/sun/star/lang/XUnoTunnel.hpp>
	#include <com/sun/star/uno/Sequence.hxx>
	#include <cppuhelper/compbase2.hxx>
	
	using namespace ::std;
	using namespace ::com::sun::star::lang;
	using namespace ::com::sun::star::uno;
	using namespace ::cppu;
	
	namespace theBiasPlanet {
		namespace unoUtilitiesTests {
			namespace localUnoObjectsTest1 {
				class Option3UnoComponent: public ImplHelper2 <XComponent, XUnoTunnel> {
					private:
						int i_usageCount = 0;
						set <Reference <::com::sun::star::lang::XEventListener>> i_eventsListeners;
					public:
						Option3UnoComponent ();
						virtual ~Option3UnoComponent ();
						virtual void SAL_CALL acquire () override;
						virtual void SAL_CALL release () override;
						virtual void SAL_CALL dispose () override;
						virtual void SAL_CALL addEventListener (Reference <::com::sun::star::lang::XEventListener> const & a_eventsListener) override;
						virtual void SAL_CALL removeEventListener (Reference <::com::sun::star::lang::XEventListener> const & a_eventsListener) override;
						virtual sal_Int64 SAL_CALL getSomething (Sequence <sal_Int8> const & a_datumIdentification) override;
				};
			}
		}
	}
#endif


theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/Option3UnoComponent.cpp

@C++ ソースコード
#include "theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/Option3UnoComponent.hpp"
#include <iostream>

namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace localUnoObjectsTest1 {
			Option3UnoComponent::Option3UnoComponent (): ImplHelper2 <XComponent, XUnoTunnel> () {
				cout << "### 'Option3UnoComponent::Option3UnoComponent ()' is called." << endl << flush;
			}
			
			Option3UnoComponent::~Option3UnoComponent () {
				cout << "### 'Option3UnoComponent::~Option3UnoComponent ()' is called." << endl << flush;
			}
			
			void SAL_CALL Option3UnoComponent::acquire () {
				cout << "### 'Option3UnoComponent::acquire ()' is called." << endl << flush;
				i_usageCount ++;
			}
			
			void SAL_CALL Option3UnoComponent::release () {
				cout << "### 'Option3UnoComponent::release ()' is called." << endl << flush;
				i_usageCount --;
				if (i_usageCount <= 0) {
					delete this;
				}
			}
			
			void Option3UnoComponent::dispose () {
				cout << "### 'Option3UnoComponent::dispose ()' is called." << endl << flush;
				::com::sun::star::lang::EventObject l_event;
				l_event.Source = Reference <Option3UnoComponent> (this);
				for (Reference <XEventListener> const & l_eventsListener: i_eventsListeners) {
					l_eventsListener->disposing (l_event);
					i_eventsListeners.erase (l_eventsListener);
				}
			}
			
			void Option3UnoComponent::addEventListener (Reference <XEventListener> const & a_eventsListener) {
				cout << "### 'Option3UnoComponent::addEventListener (Reference <XEventListener> const & a_eventsListener)' is called." << endl << flush;
				i_eventsListeners.insert (a_eventsListener);
			}
			
			void Option3UnoComponent::removeEventListener (Reference <XEventListener> const & a_eventsListener) {
				cout << "### 'Option3UnoComponent::removeEventListener (Reference <XEventListener> const & a_eventsListener)' is called." << endl << flush;
				i_eventsListeners.erase (a_eventsListener);
			}
			
			sal_Int64 SAL_CALL Option3UnoComponent::getSomething (Sequence <sal_Int8> const & a_datumIdentification) {
				return (sal_Int64) this;
			}
		}
	}
}


Objector 44A
まあ、オプション3に固執しなければならない理由は特にないな。

Hypothesizer 7
前セクションのオプション4に対しては、'::cppu::WeakComponentImplHelper%追加されるUNOインターフェイスの数%'を使用することができますが、それは、'XInterface'の全体、'::com::sun::star::lang::XTypeProvider'の全体、'::com::sun::star::uno::XWeak'の全体、'::com::sun::star::lang::XComponent'の全体を実装済みのものです。. . .実は、'::cppu::PartialWeakComponentImplHelper%追加されるUNOインターフェイスの数%'もあり、それは、'::com::sun::star::lang::XComponent'を拡張しているが、実際に'::com::sun::star::lang::XComponent'のメソッド群を実装はしていないものですが、私はそれの必要性を理解しません、なぜなら、なぜ、単に'::cppu::WeakImplHelper%追加されるUNOインターフェイスの数%'を使用して、'::com::sun::star::lang::XComponent'を追加UNOインターフェイスとして追加しないのでしょうか?

以下は、使用例です。

theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/Option4UnoComponent.hpp

@C++ ソースコード
#ifndef __theBiasPlanet_unoUtilitiesTests_localUnoObjectsTest1_Option4UnoComponent_hpp__
#define __theBiasPlanet_unoUtilitiesTests_localUnoObjectsTest1_Option4UnoComponent_hpp__
	#include <cppuhelper/compbase1.hxx>
	#include <com/sun/star/lang/XUnoTunnel.hpp>
	#include <osl/mutex.hxx>
	
	using namespace ::std;
	using namespace ::com::sun::star::lang;
	using namespace ::com::sun::star::uno;
	using namespace ::cppu;
	using namespace ::osl;
	
	namespace theBiasPlanet {
		namespace unoUtilitiesTests {
			namespace localUnoObjectsTest1 {
				class Option4UnoComponent: public WeakComponentImplHelper1 <XUnoTunnel> {
					public:
						Option4UnoComponent (Mutex & a_unoMutex);
						virtual ~Option4UnoComponent ();
						virtual sal_Int64 SAL_CALL getSomething (Sequence <sal_Int8> const & a_datumIdentification) override;
				};
			}
		}
	}
#endif


theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/Option4UnoComponent.cpp

@C++ ソースコード
#include "theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/Option4UnoComponent.hpp"
#include <iostream>

namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace localUnoObjectsTest1 {
			Option4UnoComponent::Option4UnoComponent (Mutex & a_unoMutex): WeakComponentImplHelper1 <XUnoTunnel> (a_unoMutex) {
				cout << "### 'Option4UnoComponent::Option4UnoComponent ()' is called." << endl << flush;
			}
			
			Option4UnoComponent::~Option4UnoComponent () {
				cout << "### 'Option4UnoComponent::~Option4UnoComponent ()' is called." << endl << flush;
			}
			
			sal_Int64 SAL_CALL Option4UnoComponent::getSomething (Sequence <sal_Int8> const & a_datumIdentification) {
				return (sal_Int64) this;
			}
		}
	}
}



Objector 44A
よさそうだな。

Hypothesizer 7
もう1個、使用できるクラステンプレート群グループがあります: '::cppu::ImplInheritanceHelper%追加されるUNOインターフェイスの数%'、それは、UNOインターフェイス群を、ある既存UNOコンポーネントに追加するためのものです。

以下は、使用例で、ここで、'::cppu::ImplInheritanceHelper1'のコンストラクタの引数群は、既存UNOコンポーネントのコンストラクタへ行きます.

theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/UnoComponentBase.hpp

@C++ ソースコード
#ifndef __theBiasPlanet_unoUtilitiesTests_localUnoObjectsTest1_UnoComponentBase_hpp__
#define __theBiasPlanet_unoUtilitiesTests_localUnoObjectsTest1_UnoComponentBase_hpp__
	#include <string>
	#include <cppuhelper/compbase1.hxx>
	#include <com/sun/star/lang/XUnoTunnel.hpp>
	#include <com/sun/star/uno/Sequence.hxx>
	
	using namespace ::std;
	using namespace ::com::sun::star::lang;
	using namespace ::com::sun::star::uno;
	using namespace ::cppu;
	
	namespace theBiasPlanet {
		namespace unoUtilitiesTests {
			namespace localUnoObjectsTest1 {
				class UnoComponentBase: public WeakImplHelper1 <XUnoTunnel> {
					private:
						string const i_unoComponentName;
					public:
						UnoComponentBase (string const & a_unoComponentName);
						virtual ~UnoComponentBase ();
						virtual sal_Int64 SAL_CALL getSomething (Sequence <sal_Int8> const & a_datumIdentification) override;
				};
			}
		}
	}
#endif


theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/UnoComponentBase.cpp

@C++ ソースコード
#include "theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/UnoComponentBase.hpp"
#include <iostream>

namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace localUnoObjectsTest1 {
			UnoComponentBase::UnoComponentBase (string const & a_unoComponentName): WeakImplHelper1 <XUnoTunnel> (), i_unoComponentName (a_unoComponentName) {
				cout << "### An instance of a local UNO component, '" << i_unoComponentName << "', is being created." << endl << flush;
			}
			
			UnoComponentBase::~UnoComponentBase () {
				cout << "### An instance of a local UNO component, '" << i_unoComponentName << "', is being deleted." << endl << flush;
				
			}
			
			sal_Int64 SAL_CALL UnoComponentBase::getSomething (Sequence <sal_Int8> const & a_datumIdentification) {
				return (sal_Int64) this;
			}
		}
	}
}


theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/ExtendedUnoComponent1.hpp

@C++ ソースコード
#ifndef __theBiasPlanet_unoUtilitiesTests_localUnoObjectsTest1_ExtendedUnoComponent1_hpp__
#define __theBiasPlanet_unoUtilitiesTests_localUnoObjectsTest1_ExtendedUnoComponent1_hpp__
	#include <com/sun/star/lang/XEventListener.hpp>
	#include <com/sun/star/uno/Sequence.hxx>
	#include <cppuhelper/compbase1.hxx>
	#include "theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/UnoComponentBase.hpp"
	
	using namespace ::std;
	using namespace ::com::sun::star::lang;
	using namespace ::com::sun::star::uno;
	using namespace ::cppu;
	
	namespace theBiasPlanet {
		namespace unoUtilitiesTests {
			namespace localUnoObjectsTest1 {
				class ExtendedUnoComponent1: public ImplInheritanceHelper1 <UnoComponentBase, ::com::sun::star::lang::XEventListener> {
					public:
						ExtendedUnoComponent1 ();
						virtual ~ExtendedUnoComponent1 ();
						virtual void SAL_CALL disposing (::com::sun::star::lang::EventObject const & a_event) override;
				};
			}
		}
	}
#endif


theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/ExtendedUnoComponent1.cpp

@C++ ソースコード
#include "theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/ExtendedUnoComponent1.hpp"
#include <iostream>

using namespace ::std;

namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace localUnoObjectsTest1 {
			ExtendedUnoComponent1::ExtendedUnoComponent1 (): ImplInheritanceHelper1 <UnoComponentBase, ::com::sun::star::lang::XEventListener> (string ("::theBiasPlanet::unoUtilities::localUnoObjectsTest1::ExtendedUnoComponent1")) {
			}
			
			ExtendedUnoComponent1::~ExtendedUnoComponent1 () {
			}
			
			void SAL_CALL ExtendedUnoComponent1::disposing (::com::sun::star::lang::EventObject const & a_event) {
			}
		}
	}
}



Objector 44A
うむ?なんで、既存UNOコンポーネントをただ普通に拡張しないのか、以下のように?

theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/BadUnoComponent.hpp

@C++ ソースコード
#ifndef __theBiasPlanet_unoUtilitiesTests_localUnoObjectsTest1_BadUnoComponent_hpp__
#define __theBiasPlanet_unoUtilitiesTests_localUnoObjectsTest1_BadUnoComponent_hpp__
	#include <com/sun/star/lang/XEventListener.hpp>
	#include <com/sun/star/uno/Sequence.hxx>
	#include "theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/UnoComponentBase.hpp"
	
	using namespace ::std;
	using namespace ::com::sun::star::lang;
	using namespace ::com::sun::star::uno;
	using namespace ::cppu;
	
	namespace theBiasPlanet {
		namespace unoUtilitiesTests {
			namespace localUnoObjectsTest1 {
				class BadUnoComponent: public UnoComponentBase, ::com::sun::star::lang::XEventListener {
					public:
						BadUnoComponent ();
						virtual ~BadUnoComponent ();
						virtual void SAL_CALL disposing (::com::sun::star::lang::EventObject const & a_event) override;
				};
			}
		}
	}
#endif


theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/BadUnoComponent.cpp

@C++ ソースコード

#include "theBiasPlanet/unoUtilitiesTests/localUnoObjectsTest1/BadUnoComponent.hpp"
#include <iostream>

using namespace ::std;

namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace localUnoObjectsTest1 {
			BadUnoComponent::BadUnoComponent (): UnoComponentBase (string ("::theBiasPlanet::unoUtilities::localUnoObjectsTest1::BadUnoComponent")) {
			}
			
			BadUnoComponent::~BadUnoComponent () {
			}
			
			void SAL_CALL BadUnoComponent::disposing (::com::sun::star::lang::EventObject const & a_event) {
			}
		}
	}
}


Hypothesizer 7
その理由は、あなたの追加UNOインターフェイスも'::com::sun::star::uno::XInterface'を拡張しており、'::com::sun::star::uno::XInterface'を再度、実装しなければならなくなるからです。

Objector 44A
ああ、'::com::sun::star::uno::XInterface'の既存UNOコンポーネントによる実装は、私のUNOインターフェイスの'::com::sun::star::uno::XInterface'を遅れ馳せに実装したりしないからな、もちろん. . .

Hypothesizer 7
単一のUNOコンポーネントベースを作成し、それを拡張して私のUNOコンポーネント群の全てを作成することの利点は、自分のUNOコンポーネント群の全インスタンス群の誕生および死を追跡できることです。


6: 結びとその先


Hypothesizer 7
これで、C++において、任意のUNOコンポーネントを定義する方法を私たちは知りました。

それを、ローカルUNOオブジェクトたちのためやリモートUNOオブジェクトたちのためにどのように使用できるのでしょうか?それを、いくつかの以降の記事群にて見ます。

任意のUNOコンポーネントを、Java、C#、Pythonで作成する方法も見ます、いくつかの以降の記事群にて。


参考資料


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