2021-05-09

60: Create and Register UNO Interface/Generate Mapping Images

<The previous article in this series | The table of contents of this series | The next article in this series>

In order to create your own UNO component, in Java, C++, C#, or Python. Generate the Java, C++, C#, and Python mapping images.

Topics


About: LibreOffice
About: Apache OpenOffice
About: The Java programming language
About: C++
About: The Python programming language
About: C#
About: LibreOffice Basic
About: Apache OpenOffice Basic

The table of contents of this article


Starting Context


  • The reader has a basic knowledge on LibreOffice or Apache OpenOffice.

Target Context


  • The reader will know how to create and register his or her own UNO interface and generate its Java, C++, C#, and Python mapping images.

Orientation


There is an article on the basic elements of UNO.

There is an article on how to build an environment for developing UNO Programs in Linux or in Windows.

There is an article on the basics of creating any LibreOffice or Apache OpenOffice extension.

There is an article on creating any console UNO client in Java, in C++, in C#, or in Python.

There is an article on creating any LibreOffice or Apache OpenOffice extension that contains any Python macros or any Basic macros.


Main Body

Stage Direction
Here are Hypothesizer 7, Objector 60A, and Objector 60B in front of a computer.


1: In Order to Create Your Own UNO Component


Hypothesizer 7
The reason why you want to create your own UNO interface will be that you want to create your own UNO component.

Objector 60A
Too bad! I want to create a service.

Hypothesizer 7
Sir, I am not sure what you mean by "service", but if you mean what I call 'UNO service', probably, you are going to create a UNO component as a requisite.

Objector 60A
You said "probably", so I don't necessarily have to create any "UNO component"!

Hypothesizer 7
You are right, sir, but as any UNO service is a UNO component registered in a factory, your UNO service will be of an existing UNO component.

Objector 60A
So? Is that wrong?

Hypothesizer 7
Not particularly, but in that case, you will not need any new UNO interface.


2: Why Is a Mapping Image Needed


Hypothesizer 7
As any UNO interface is a programming-language-independent entity, you will need the mapping images in your programming languages.

Objector 60B
"your programming languages"? What are my programming languages?

Hypothesizer 7
I do not know, madam. . . . In what programming language, are you going to create your UNO component?

Objector 60B
Well, you tell me.

Hypothesizer 7
. . . I cannot tell you, madam.

Objector 60B
Then, C#, perhaps.

Hypothesizer 7
Then, it is your programming language.

Objector 60B
But I have only one programming language yet, while you said "your programming languages" (plural)!

Hypothesizer 7
If you create just a C# UNO client, you will not need to create any UNO component, so any UNO interface.

Objector 60B
Huh? Why?

Hypothesizer 7
Because then, ordinary C# classes will do. You need a UNO component because you need an object that can be handled from another programming-language environment, which may be a C# environment, but not necessarily so.

Objector 60B
Huh? Are you all right? You seem to be talking in a delirium.

Hypothesizer 7
. . . You should understand what UNO is for.

Objector 60B
Anyway, why is a "mapping image" needed?

Hypothesizer 7
Supposing that you are going to create a UNO component in Java, you need the UNO interface as a Java interface.

Objector 60B
Why?

Hypothesizer 7
Because the UNO component has to implement the UNO interface, but Java does not allow the UNO component to implement the programming-language-independent UNO interface.

Objector 60B
Does it not? It is so stingy!

Hypothesizer 7
. . . Such a programming-language-independent entity is just on the outside of its expectation than it is stingy.

Objector 60A
What if I am accessing a remote UNO object in a programming language, not creating a UNO component in the programming language?

Hypothesizer 7
Ah, that depends on the programming language: Java, C++, and C# require the mapping images anyway, but Python or Basic does not.

Objector 60A
Why the difference?

Hypothesizer 7
Because Python or Basic is not any statically-typed programming language.

Objector 60A
Do you mean that Python doesn't require the mapping image even if a UNO component is created in it?

Hypothesizer 7
No, I do not mean that: Python requires the mapping image in that case.

Objector 60A
How about Basic?

Hypothesizer 7
Basic does not allow creating any UNO component at all, because it does not allow creating any class, although it allows creating listener objects, which does not require any mapping image.


3: Creating a UNO Interface


Hypothesizer 7
In order to create a UNO interface, we create a '.idl' file like this.

theBiasPlanet/unoDatumTypes/testUnoExtension/XTestUnoExtensionUnoInterface.idl

@UNO IDL Source Code
// # Change the defined variable name Start
#ifndef __theBiasPlanet_unoDatumTypes_test_XTest_idl__
#define __theBiasPlanet_unoDatumTypes_test_XTest_idl__
// # Change the defined variable name End

#include <com/sun/star/uno/XInterface.idl>
// # Add necessary idls Start
#include <com/sun/star/lang/IllegalArgumentException.idl>
// # Add necessary idls End

// # Change the module name
module theBiasPlanet {
	module unoDatumTypes {
		module test {
			// # Change the interface name
			interface XTest {
				// # Change the super interface and add more super interfaces if necessary
				interface ::com::sun::star::uno::XInterface;
				// # Add methods START
				string test1 ( [in] string a_name) raises (com::sun::star::lang::IllegalArgumentException);
				// # Add methods END
			};
		};
	};
};

#endif

Objector 60A
The file is in the package (or should I call it "module"?) directory . . .

Hypothesizer 7
In fact, the location or the name does not really matter, but I place '.idl' files in that structure for ordering's sake.

Objector 60A
Well, the code is self-explanatory, mostly.

Hypothesizer 7
Note that it is better to put the super UNO interface, "::com::sun::star::uno::XInterface" in this case, there, because you can add more super UNO interfaces there, if necessary.

Objector 60A
Being told "better", without being given any other option . . .

Hypothesizer 7
It can be written also like "interface XTest: ::com::sun::star::uno::XInterface {", but that way allows only one super UNO interface.

Objector 60A
What else can be specified instead of "[in]"?

Hypothesizer 7
'[out]' or '[inout]'. It should be noted that for any modification to (not only any replacement of) the argument object to be propagated to the method caller, generally speaking, it has to be '[out]' or '[inout]'.

Objector 60B
Huh? Are you talking in your sleep?

Hypothesizer 7
Madam, in Java, any modification to the argument object is visible from the method caller, but it is not so in UNO, generally speaking.

Objector 60B
What was that doggerel about "replacement"?

Hypothesizer 7
I talked about replacing the address in the pointer.

Objector 60B
Huh? "pointer"?

Hypothesizer 7
You know that any Java so-called "reference type" variable is not any "reference", but a pointer.

Objector 60B
Huh? It's a reference, right?

Hypothesizer 7
No. Such a sloppy terminology is the major cause of some confusions; if it is called pointer, the point will be crystal clear.

Objector 60A
Why were you saying "generally speaking"?

Hypothesizer 7
If the situation is totally local in a Java environment, the modification to any '[in]' argument will be visible from the method caller, because the call will be just a normal Java method call.

Objector 60A
That's odd.

Hypothesizer 7
That is certainly odd, but is a fact.


4: Compiling and Archiving the '.idl' Files


Hypothesizer 7
As we have created the '.idl' source files, let us compile each of them.

In fact, this is a command to do that.

@bash or CMD Source Code
%the LibreOffice or Apache OpenOffice product directory%/sdk/bin/idlc -w -C -I%the LibreOffice or Apache OpenOffice product directory%/sdk/idl -I%an additional UNOIDL sources base directory% -I%another additional UNOIDL sources base directory% -O%the output directory% %the source file%

Objector 60B
. . . So, there is such a command there.

Hypothesizer 7
Only if you have installed the LibreOffice or Apache OpenOffice SDK.

Objector 60B
Huh? What is that?

Hypothesizer 7
How to install it is in a previous article (for Linux or for Windows).

Objector 60B
Ah, so.

Hypothesizer 7
Anyway, we have to archive the generated UNO datum type unmerged files into a UNO datum types merged file, like this.

@bash or CMD Source Code
%the LibreOffice or Apache OpenOffice product directory%/regmerge %the output file% /UCR %a UNO datum type unmerged file% %another UNO datum type unmerged file%


5: Registering the UNO Datum Types Merged File


Hypothesizer 7
We will register the UNO datum types merged file.

There are 2 ways: 1) put it in the '%the LibreOffice or Apache OpenOffice product directory%/program/types' directory 2) register it via an extension.

Objector 60A
Can I just copy it there?

Hypothesizer 7
Or you can create a symbolic link there, but anyway, you have to restart the LibreOffice or Apache OpenOffice instance.

For the way 2, we can put the UNO datum types merged file into the structure and add a node into the manifest, like this.

@XML Source Code
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE manifest:manifest PUBLIC "-//OpenOffice.org//DTD Manifest 1.0//EN" "Manifest.dtd">
<manifest:manifest xmlns:manifest="http://openoffice.org/2001/manifest">
	~
	<manifest:file-entry manifest:media-type="application/vnd.sun.star.uno-typelibrary;type=RDB" manifest:full-path="theBiasPlanet.test.unoExtension.rdb"/>
	~
</manifest:manifest>

Objector 60A
Is it visible from other extensions?

Hypothesizer 7
A good point. Actually, it is visible globally.


6: Generating the Mapping Images



6-1: The Java Mapping Images


Hypothesizer 7
In order to generate the Java mapping images of the UNO interfaces contained in the UNO datum types merged file, we execute a command like this.

@bash or CMD Source Code
%the LibreOffice or Apache OpenOffice product directory%/sdk/bin/javamaker -nD -X%the LibreOffice or Apache OpenOffice product directory%/program/types.rdb -X%the LibreOffice or Apache OpenOffice product directory%/program/types/offapi.rdb %the UNO datum types merged file% -O%the output base directory%

Objector 60A
. . . Is that it?

Hypothesizer 7
That is it, but of course, the generated class files have to be referred to by any program that needs them.

Objector 60B
"referred to"? How can they be "referred to"?

Hypothesizer 7
If your program is an in-LibreOffice-or-Apache-OpenOffice-JVM program, there are 2 ways: 1) register the generated class files Jar file in the 'URE_MORE_JAVA_TYPES' item in '%the LibreOffice or Apache OpenOffice product directory%/program/fundamentalrc' in Linux or in '%the LibreOffice or Apache OpenOffice product directory%\program\fundamental.ini' in Windows 2) include the generated class files in the extension Jar file or the macro Jar file.

Objector 60B
"the generated class files Jar file"? I don't have one.

Hypothesizer 7
You have to create it yourself.

Anyway, it should be noted that the classes in any extension Jar file or macro Jar file are visible only in the extension or macro.

Objector 60B
So, should a class that is to be referred to in multiple extensions be registered by the way 1?

Hypothesizer 7
Or you can put the class file into the multiple extension Jar files.

Objector 60B
What if my program isn't an in-LibreOffice-or-Apache-OpenOffice-JVM program?

Hypothesizer 7
That should mean that your program is an independent program, for example a UNO client. Then, of course, it is just a matter of setting the classes paths.


6-2: The C++ Mapping Images


Hypothesizer 7
In order to generate the C++ mapping images of the UNO interfaces contained in the UNO datum types merged file, we execute a command like this.

@bash or CMD Source Code
%the LibreOffice or Apache OpenOffice product directory%/sdk/bin/cppumaker -nD -X%the LibreOffice or Apache OpenOffice product directory%/program/types.rdb -X%the LibreOffice or Apache OpenOffice product directory%/program/types/offapi.rdb %the UNO datum types merged file% -O%the output base directory%

In this case, what are generated are header files.

Objector 60B
That's odd: C++ mapping images are source files, while Java mapping images are binary files . . .

Hypothesizer 7
Actually, it stands to sense: as any C++ class is a blueprint, not any objective object, the mapping images cannot be in any object file.

Objector 60B
So, the generated header files can be referred to . . . how?

Hypothesizer 7
As any header file is not something to be referred to at run time, but to be included at compile time, the generated header files are not necessary to be referred to at run time.


6-3: The C# Mapping Images


Hypothesizer 7
In order to generate the C# mapping images of the UNO interfaces contained in the UNO datum types merged file, we execute a command like this.

@bash or CMD Source Code
%the LibreOffice or Apache OpenOffice product directory%\sdk\bin\climaker -X %the LibreOffice or Apache OpenOffice product directory%\program\types.rdb -X %the LibreOffice or Apache OpenOffice product directory%\program\types\offapi.rdb %the UNO datum types merged file% -O %the output file% -r %the LibreOffice or Apache OpenOffice product directory%\sdk\cli\cli_basetypes.dll -r %the LibreOffice or Apache OpenOffice product directory%\sdk\cli\cli_oootypes.dll -r %the LibreOffice or Apache OpenOffice product directory%\sdk\cli\cli_uretypes.dll -r %the LibreOffice or Apache OpenOffice product directory%\sdk\cli\cli_cppuhelper.dll -r %the LibreOffice or Apache OpenOffice product directory%\sdk\cli\cli_ure.dll

Objector 60A
Is the assembly created directly?

Hypothesizer 7
Yes, as C# does not have such thing as a separate object file.

And of course, the assembly has to be referred to by your program at compile time and at run time.


6-4: The Python Mapping Images


Hypothesizer 7
For Python, there is no operating system command to generate the mapping images.

Objector 60A
Huh? Can't I use the UNO interfaces in Python, then? Damn! Despicable!

Hypothesizer 7
Calm down, please, sir. You can use them in Python, by generating the mapping images dynamically.

Objector 60A
What do you mean by "dynamically"?

Hypothesizer 7
This Python code generates a mapping image.

@Python Source Code
import uno

XTest: Any = uno.getClass ("theBiasPlanet.unoDatumTypes.test.XTest")

Objector 60A
. . . Does that "XTest" contain a class as "theBiasPlanet.unoDatumTypes.test.XTest"?

Hypothesizer 7
Yes, it does.

Objector 60A
. . . How can it be used?

Hypothesizer 7
In fact, in order to handle any remote UNO object, you do not need to explicitly use it, as Python UNO internally does the work; in order to create a UNO component (typically, a listener) in Python, you can (and have to) use the class as a super class of your UNO component, like this.

@Python Source Code
from unohelper import Base as UnoBase

class Test1Test (UnoBase, XTest):
	~


References


<The previous article in this series | The table of contents of this series | The next article in this series>