Home > C# > 目的別資料 > Office文書の操作 > Libre Office

クライアント・プログラムを記述する

新規作成日 2017-11-30
最終更新日

クライアント・プログラムを記述する

原文「Writing Client Programs

クライアント・プログラムを構築するには、少なくともcli_types.dllとcli_cppuhelper.dllを参照する必要があります。また、cli_ureは、クラスの1つが使用されているときに参照できます。これらのライブラリは、GACとオフィス・インストールのプログラム・フォルダの中にインストールされます。参照は、例えば、C++(管理された拡張で)は、/A、または、C#コンパイラでは、/referenceの特定のコンパイラ・スイッチで行われます。また、C ++では、#usingを使用してdllを指定する必要があります。

 #using <mscorlib.dll>  
 #using <cli_types.dll>

あなたのプロジェクトを作成するとき、Visual Studioによるc#では、mscorlibが、含まれます。あなたの参照でそれを見たい場合は、.csprojファイルを編集して追加してください。:

<ItemGroup>
   <Reference Include="mscorlib" />
   <Reference Include="System" />

cli_basetypes、cli_cppuhelper、cli_oootypes、cli_ureとcli_uretypes .dllファイルのために、私は、Visual Studioのプロジェクト参照に、それらを追加します。私は、ここでは、cli_cppuhelperが、:\WINDOWS\assembly\GAC_32\cli_cppuhelper\1.0.22.0__ce2cb7e279207b9e\cli_cppuhelper.dllだと見つけました。そして、 GAC_MSIL中にある他のものは近くの、:\WINDOWS\assembly\GAC_MSIL\cli_basetypes\1.0.19.0__ce2cb7e279207b9e\cli_basetypes.dllにあります。続いて、クラスの1つが使用されるとき、ソースに以下を追加してください。:

using unoidl.com.sun.star.lang;
 using unoidl.com.sun.star.uno;
 using unoidl.com.sun.star.bridge;
 using unoidl.com.sun.star.frame;
 using unoidl.com.sun.star.util;

次の例では、オフィス処理に実行することで、どのように、提供したサービスを使用するかを説明します。:

すべてのリモート・クライアント・プログラムの開始位置は、コンポーネント・コンテキストです。それは、クラスuno.util.Bootstrapで提供される、static defaultBootstrap_InitialComponentContextによって作成されます。コンテキストは、UNOコンポーネントを作成するためのサービスマネージャを提供します。しかしながら、これらのコンポーネントは、依然として、クライアント処理にローカルです。すなわち、それら、実行中のオフィスからではありません。そして、その結果、実行中のオフィスに影響を与えることはできません。実際に必要なものは、実行中のオフィスのサービス・マネージャーです。それを実現するためには、ローカル・サービス・マネージャーで提供される、コンポーネントcom.sun.star.bridge.UnoUrlResolverが、使われます。UnoUrlResolverは、リモート・オフィスに接続して、クライアント処理において、オフィスのサービス・マネージャーのプロキシを作成します。サンプルコード(OOo 2.x)は、次のとおりです。:

//C# example
System.Collections.Hashtable ht = new System.Collections.Hashtable();
ht.Add("SYSBINDIR", "file:///<office-dir>/program");
  unoidl.com.sun.star.uno.XComponentContext xLocalContext =
           uno.util.Bootstrap.defaultBootstrap_InitialComponentContext(
           "file:///<office-dir>/program/uno.ini", ht.GetEnumerator());

unoidl.com.sun.star.bridge.XUnoUrlResolver xURLResolver =
                  (unoidl.com.sun.star.bridge.XUnoUrlResolver)
                          xLocalContext.getServiceManager().
                                   createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver",
                 xLocalContext);

unoidl.com.sun.star.uno.XComponentContext xRemoteContext =
         (unoidl.com.sun.star.uno.XComponentContext)xURLResolver.resolve(
                  "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext");

unoidl.com.sun.star.lang.XMultiServiceFactory xRemoteFactory =
         (unoidl.com.sun.star.lang.XMultiServiceFactory)
                  xRemoteContext.getServiceManager();

OOo 3.xのための、コードは、これです。:

//C# example for OOo 3.x
// OOo 3.xのC#の例
//Workaround which is needed when using a socket connection
// ソケット接続を使用するとき、必要な回避策
//This will initialize the Windows socket library.
// これは、Windowsのソケット・ライブラリを初期化します。
System.Net.Sockets.Socket s = new System.Net.Sockets.Socket(
AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
//
String sUnoIni = "file:///d:/OpenOffice.org%203/URE/bin/uno.ini";
XComponentContext xLocalContext =
    uno.util.Bootstrap.defaultBootstrap_InitialComponentContext(sUnoIni, null);
XMultiComponentFactory xLocalServiceManager = xLocalContext.getServiceManager();

XUnoUrlResolver xUrlResolver =
    (XUnoUrlResolver)xLocalServiceManager.createInstanceWithContext(
        "com.sun.star.bridge.UnoUrlResolver", xLocalContext);

XMultiServiceFactory multiServiceFactory =
    (XMultiServiceFactory)xUrlResolver.resolve(
         "uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager");

他の方法として、パイプ接続を使用することができ、この場合、あらかじめソケットを作成する必要はありません。

//C# example for OOo 3.x
String sUnoIni = "file:///d:/OpenOffice.org%203/URE/bin/uno.ini";
XComponentContext xLocalContext =
    uno.util.Bootstrap.defaultBootstrap_InitialComponentContext(sUnoIni, null);
XMultiComponentFactory xLocalServiceManager = xLocalContext.getServiceManager();

XUnoUrlResolver xUrlResolver =
    (XUnoUrlResolver)xLocalServiceManager.createInstanceWithContext(
        "com.sun.star.bridge.UnoUrlResolver", xLocalContext);

XMultiServiceFactory multiServiceFactory =
    (XMultiServiceFactory)xUrlResolver.resolve(
         "uno:pipe,name=some_unique_pipe_name;urp;StarOffice.ServiceManager");

通常、オフィス・インストールにおいて、uno.ini(URE/binフォルダー)に、パスを提供します。その場合、そして、特定のブートストラップ変数を提供したくない場合、(defaultBootstrap_InitialComponentContextの2つ目のパラメータ)続いて、引数を取らないdefaultBootstrap_InitialComponentContextのバージョンを使用することができます。:

XComponentContext xLocalContext = 
    uno.util.Bootstrap.defaultBootstrap_InitialComponentContext();
XMultiServiceFactory fac = (XMultiServiceFactory) m_xContext.getServiceManager();

手元にある実行中のオフィスのファクトリーで、リモート・オフィスのすべてのコンポーネントにアクセスできます。

実行中のオフィスに接続するクライアントのために、オフィスは、適切なパラメータで開始されている必要があります。この場合、コマンド・ラインはこのように見えます。:

soffice -accept=socket,host=localhost,port=2002;urp

あるいは、パイプ・コネクションを用いて

soffice -accept=pipe,name=pipe_name;urp

OOoのための役に立つ、他のコマンド・ライン・オプションは、以下の通りです。:

-minimized -invisible -nologo -nolockcheck -nodefault

UNOプロセス間接続」を参照してください。

OOo3.0では、fundamental.iniに、パスが含まれるiniファイルを提供する必要があります。defaultBootstrap_InitialComponentContext関数を使用するとき、iniファイルは、クライアント・プログラムと(拡張子なしで)同じ名前を持つ必要があります。例えば、プログラムは、client.exeの名前が付けられています。そして、また、client.iniが、同じフォルダの中にある必要があります。fundamental.iniへのパスは、ファイルURLである必要があります。それは、特殊文字をエンコードする必要があります。例えば、スペースは、%20として表現されています。例:

[Bootstrap]
URE_BOOTSTRAP=file:///d:/OpenOffice.org%203/program/fundamental.ini

もう一つ、開始する簡単な方法とOOoへの接続は、関数uno.util.Bootstrap.bootstrapを使用することです。この関数は、レジストリ(HKEY_CURRENT_USER\Software\OpenOffice.org\UNO\InstallPathまたはHKEY_LOCAL_MACHINE\Software\OpenOffice.org\UNO\InstallPath)または環境変数UNO_PATHを使用してOOoを検索します。この関数は、最初にHKEY_CURRENT_USERキーを使用します。そして、それが存在しない場合、HKEY_LOCAL_MACHINEキーを使用します。オフィスが開始しない場合、これらのキーを確認します。また、PATH環境変数に別のオフィスへのプログラム・パスが含まれていないことを確認してください。

//C# example. OOo is started automatically. 
// C#の例。OOoは、自動的に開始されます。
 XComponentContext xContext = uno.util.Bootstrap.bootstrap();

コンテクストを取得するこのメソッドは、iniファイルを全く必要としません。制限は、常にパイプ接続を使用することです。言い換えると、それは、ローカルOOoには適切ですが、別のマシンでは、適していません。

実行中のオフィスに依存しない、UNOアプリケーションを記述することができます。続いて、あなたは、通常は、登録されたサービスのデータベースを提供します。詳細については、手作業によるコンポーネントのインストールを確認して下さい。

CLI-UNO言語結合は、CLI言語で記述される、UNOコンポーネントをサポートしていません。その代わりに、それは、CLIクライアント・プログラムとオフィスの間の連絡役として機能します。クライアント・プログラムは、通常、オフィスからUNOオブジェクトを取得し、その上で操作を実行します。その結果、UNOインターフェイスの実装は、めったに、必要ありません。

UNOオブジェクトから通知を受け取るために、適切なインターフェイスを実装することが必要です。また、UNOメソッドへの引数としてオブジェクトを使用するために、インターフェイスを実装することができます。

インターフェイスは、1つ以上のインターフェイスから派生する、クラスを宣言することによって実装されます。そして、それは、interfaceメソッドの実装を提供します。これを、さまざまなCLI言語のそれぞれのドキュメントで、どのように、実行するかを取り扱います。

オーバーライド問題

原文「The Override Problem」

「オーバーライド問題」という用語は、発生する問題を説明します。基準となるオブジェクトの仮想関数に到達できないとき、なぜなら、インターフェイス・メソッドは、基底クラスの実装をオーバーライドします。例えば、すべてのCLIオブジェクトは、System.Objectから派生します。インターフェイスが、メソッドを持っている場合、System.Objectのメソッドの1つとして、同じシグネチャを持っています。そのため、インターフェイス・メソッドが、仮想である場合、System.Objectのそれぞれのメソッドには、到達できません。

using namespace System;
 
public __gc __interface XFoo
{
    public:
            virtual String* ToString();
};

public __gc class Foo : public XFoo
{
    public:
            virtual String* ToString()
    {
    return NULL;
    }
};

例えば、次のインターフェイスXFooの宣言と、それを実装しているクラスについて考えてみてください。

 int main(void)
 {
         Foo * f = new Foo();
         Object * o = f;
         f->ToString(); // calls Foo.ToString
         o->ToString(); // calls Foo.ToString
 
     return 0;
 }

インスタンスのメソッドのToStringが、呼び出される場合、続いて、インターフェイス・メソッドの実装が、呼び出されます。例えば、

これは、意図されていないかもしれません。なぜなら、おそらく、インターフェイス・メソッドは、System.Objectの同名のものとは、別の意味を持っています。

ソリューションは、インターフェイス・メソッドを非仮想にすることなく、インターフェイス・メソッドが、System.Objectのメソッドを上書きするのを防ぎます。CLIは、ILコードのメソッド・ヘッダに添付される「newslot」フラグの改善策を提供します。CLI言語は、「newslot」でメソッドを表示するための、別の手段を備えているかもしれません。

次の例は、さまざまな言語で、Object.ToStringを呼び出すことができる、XFooを実装する方法を示しています。

//C++
 //interface methods should be qualified with the interface they belong to
 public __gc class A: public XFoo
 {
 public:
         virtual String* XFoo::ToString()
         {
                  Console::WriteLine("A::foo");
                  return NULL;
         }
 };

インターフェイス・メソッドは、それらが属しているインターフェイスで修飾する必要があります。

けれども、CLIメソッド・ヘッダには、最終的な属性が、含まれているため、XFoo::ToStringは、継承しているクラスで上書することができない仮想です。再度、XFooから派生し、実装を提供しますが、継承しているクラスの1つで、行うことができます。

C#では、さまざまな方法で実装を提供しています。:

 // IL contains: newslot final virtual
// ILには、以下のものが含まれています。:newslot final virtual
 public new string ToString()
 {
 }

新しいキーワードは、CLIメソッド・ヘッダに、newslot属性を挿入します。この実装は、継承しているクラスでは、上書きすることができません。

//IL contains: newslot virtual // ILには、以下のものが含まれています。:newslot virtual public new virtual string ToString() { }

このメソッドは、派生クラスで上書きすることができます。

 // Using a qualified method name for the implementation. The virtual 
 //modifier is not allowed
 // 実装のために、修飾付きのメソッド名を使用します。
 // 仮想修飾子は、使用できません。
 string XFoo.ToString()
 {
                   return null;
 }

この実装は、派生クラスでは、上書きすることができません。実装するクラスのインスタンスは、メソッドが、呼び出される前に、XFooにキャストする必要があります。

 'VB .NET
 Public Shadows Function ToString() As String Implements XFoo.ToString
          Console.WriteLine("Foo.toString")
 End Function

この実装は、派生クラスでは、上書きすることができません。

 Public Overridable Shadows Function ToString() As String _
 Implements XFoo.ToString
         Console.WriteLine("Foo.toString")
 End Function
このメソッドは、上書きできます。

重要なインターフェイスと実装(ヘルパー・クラス)

原文「Important Interfaces and Implementations (Helper Classes)

UNOオブジェクトは、いくつかが、常に要件に依存している一連のUNOインターフェイスを実装しています。以下のインターフェイスは、オフィスのプログラムディレクトリ内のcli_types.dllというアセンブリに属しています。:

少し簡単に、オブジェクト開発を作成するために、言語結合は、上記のインターフェイスのほとんどのためにヘルパー実装を提供しています。ヘルパー・クラスは、uno.util名前空間に属しており、cli_ure.dllと呼ばれるアセンブリに含まれています。C++やJavaのものと類似しているリスナー・コンテナを実装する見つからないヘルパーに注意して下さい。それが存在する主な理由は、イベント・リスナーの自動通知を確実に行うことです。(com.sun.star.lang.XComponentcom.sun.star.lang.XEventListenerを確認して下さい)。CLI言語は、特定の場合、不必要なヘルパー・クラスを作成するイベント(デリゲート)のために、簡単な仕組みを提供しています。なぜなら、イベント通知は、言語の機能を使って、簡単に実装されます。

uno.util.WeakBase

このクラスは、XTypeProviderXWeakインターフェイスを実装しています。XWeakは、UNOの弱い参照の仕組みを実装するために用いられます。そして、System.WeakReferenceが、使われていないのは奇妙に思われるかもしれません。あなたは、あなたのUNOオブジェクトが、弱い参照をサポートしていない、他の言語環境内で保持されることを覚えておく必要があります。この方法では、弱い参照は、UNOの概念として実装されています。もちろん!すべてのコンポーネントやアプリケーションができるように、ヘルパーの実装が、System.WeakReferenceを使用している限り、UNOインタフェースへの呼び出しには渡されません。また、コンパイラは、適切に実装をコンパイルすることができません。

uno.util.WeakComponentBase

このクラスは、uno.util.WeakBaseから派生して、XComponentインターフェイスを実装します。コンポーネントが、特別なクリーンアップを実行する必要がある場合、基底クラスとして、このクラスを使用します。クラスは、オブジェクトの廃棄に呼び出される、2つの保護されたメンバー関数を持っています。:

  • すべての登録されたイベント・リスナーに通知する前に、呼び出されます。
  • すべての登録されたイベント・リスナーに通知する後に、呼び出されます。この方法では、リソースのクリーンアップを実行する必要があります。

uno.util.WeakComponentBaseから継承して、適切なメソッドを上書きします。

このエントリーをはてなブックマークに追加

Home PC C# Illustration

Copyright (C) 2011 Horio Kazuhiko(kukekko) All Rights Reserved.
kukekko@gmail.com
ご連絡の際は、お問い合わせページのURLの明記をお願いします。
「掲載内容は私自身の見解であり、所属する組織を代表するものではありません。」