Integrating LibreOffice into C++

By , last updated November 22, 2016

At our math website we publish printable PDF worksheets for school children. We’ve just started publishing crosswords, while relatively easy to create, they require much work to make them into tasks.

A workflow consists of multiple, repetitive tasks, which could be automated. And that’s what I’m doing with LibreOffice. I’m using LibreOffice as it’s more updated than OpenOffice. Even though they have a lot in common, LibreOffice just feels more right for C++ code than OpenOffice.

This post is the first in a series of LibreOffice C++ tutorials on how to integrate and use LibreOffice with C++.

The first step in integrating LibreOffice into C++, is having both the LibreOffice suite installed and the SDK. I’ll be covering Windows in this guide, as it’s more difficult to get started with than on various Linux distributions.

Installation

Head over to https://www.libreoffice.org/download/libreoffice-fresh/ and download the latest release and SDK. Both should be available at that page.

Installation order:

  1. Install LibreOffice first.
  2. Then install the corresponding LibreOffice SDK.

Generate C++ headers

Contrary to regular C++ libraries, the LibreOffice SDK doesn’t come with all headers. In fact, most of the headers have to be generated by a tool calledcppumaker. It’s difficult tool to get started with, as it have some requirements and assumptions whose are not very well documented by the program itself.

Most issues can be solved by looking at the error messages, some searching online and some experimenting. Here I’ll outline most of the errors I encountered.

Cppumaker works by reading some database files, and then generates C++ types from those database files. Those database files comes with the LibreOffice suite and are placed a couple of places in the installation folder.

Read also  Getting rid of those pesky C-macros in C++-code (QSORT)

The bridge between a language and LibreOffice itself is called UNO.

Create a staging directory for cppumaker

As most people, I don’t like to work directly with system wide files when developing and experimenting with things just like this. Sadly cppumaker sort of requires to be able to place files directly in the installation folder to the SDK.

We’re still going to create a staging directory, just for the extra challenge.

Create a staging directory somewhere. Where is not important. Create a script called make_cpp_types.bat in that folder. The output directory out doesn’t have to exist. It will be created automatically by cppumaker.

Script for making C++ headers

Most of the time I make scripts when doing complex operations on the Windows command line. This is no exception. It’s easier to just restart the script, than to manually enter PATH environment variables every time you accidentally wipe the PATH variable or close the command line window.

With the LibreOffice SDK, there are a couple of items in various folders. The program cppumaker is in one folder, while it’s dependencies are in an other directory, while the RDB are in some other folders. It’s a mess to fiddle with manually on the command line.

Here is the beginning of a batch script gathering the pieces together.

rem Start path
set STARTDIR=%cd%

rem Libre paths. May have to be adjusted
set LIBRE=C:\Program Files (x86)\LibreOffice 5
set LIBREPROGRAM=%LIBRE%\program
set LIBRESDK=%LIBRE%\sdk\bin

set PATH=%LIBREPROGRAM%;%LIBRESDK%;%PATH%

At this point, all we’ve done is to modify the PATH variable to contain the path to cppumaker and it’s dependencies. This is to be able to run cppumaker.

Next up is making variables for the three databases to generate types from. Those are types.rdb, offapi.rdb and oovbaapi.rdb.

  • types.rdb – General types.
  • offapi.rbd – API to the LibreOffice applications themselves.
  • oovbaapi.rdb –¬†OpenOffice / LibreOffice VBA API.
set STAGE=%STARTDIR%\out
set TYPES=%LIBREPROGRAM%\types.rdb
set OOVBAAPI=%LIBREPROGRAM%\types\oovbaapi.rdb
set OFFAPI=%LIBREPROGRAM%\types\offapi.rdb

Wrapping it up.

The final command is calling cppumaker with the correct parameters. It is very picky about the parameters, so be careful.

Read also  How to dynamically load native DLLs from C#

With the variables from above, calling cppumaker will look like this.

cppumaker -O "%STAGE%" "%TYPES%" "%OOVBAAPI%" "%OFFAPI%"

pause

When the script is done running, there should be a bunch of other files and folders. Copy those files back to the SDK directory, keeping the same directory structure, or adjust the script so the staging directory points to the SDK include directory and run the script as administator.

For the lazy, the stage directory for non-staging is:

set STAGE=C:\Program Files (x86)\LibreOffice 5\sdk\include

The final script should look something like this, adjusted for your paths.

rem Libre paths. May have to be adjusted
set LIBRE=C:\Program Files (x86)\LibreOffice 5
set LIBREPROGRAM=%LIBRE%\program
set LIBRESDK=%LIBRE%\sdk\bin

set PATH=%LIBREPROGRAM%;%LIBRESDK%;%PATH%

set STAGE=%STARTDIR%\out
set TYPES=%LIBREPROGRAM%\types.rdb
set OOVBAAPI=%LIBREPROGRAM%\types\oovbaapi.rdb
set OFFAPI=%LIBREPROGRAM%\types\offapi.rdb

rem Alternate STAGE directory, uncomment and run as Administrator
rem to generate headers into the LibreOffice SDK incldue directory
rem set STAGE=C:\Program Files (x86)\LibreOffice 5\sdk\include

cppumaker -O "%STAGE%" "%TYPES%" "%OOVBAAPI%" "%OFFAPI%"

pause

Troubleshooting

It’s not trivially easy to make this program generate the headers, and there are many pitfalls getting it just right. And it has to be just right.

Can’t find DLLs

If you get messageboxes saying that either sal3.dll, salhelper3MSC.dll and/or unoidllo.dll are missing, the PATH variable isn’t set properly. It has to contain the LibreOffice program directory for the DLLs to be found.

cppumaker-sal3

cppumaker-salhelper3msc

cppumaker-unoidllo

ERROR: No such file

The error ERROR: No such file is because there is a slash at the end of the output path. Remove the slash and try again.

rem Wrong STAGE
set STAGE=%STARTDIR%\out\

rem Correct STAGE (notice the slash at the end)
set STAGE=%STARTDIR%\out

ERROR: cannot open for writing

You are trying to write to the installation directory, for which you need administrator privileges. Run the script as administrator and try again.

ERROR: Unknown entity ‘com.sun.star.lang.EventObject’

The file types.rdb is not provided on the command line, only the file offapi.rdb. Provide both and try again.

ERROR: Unknown entity ‘com.sun.star.uno.RuntimeException’

Same as above, but only with oovbaapi.rdb. The file types.rdb must be provided on the command line to cppumaker.

Integrating into Visual C++

Up until now the article have been about just getting the headers to work. Actually using the headers is something else. But before that, Visual Studio must know where to locate the headers.

Add C:\Program Files (x86)\LibreOffice 5\sdk\include to Additional Include Directories.

visual-studio-libreoffice-include

If properly done, then this code should compile.

#include <sal/main.h>
#include <cppuhelper/bootstrap.hxx>

#include <osl/file.hxx>
#include <osl/process.h>
#include <rtl/process.h>

#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/bridge/XUnoUrlResolver.hpp>
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/registry/XSimpleRegistry.hpp>

#include <string.h>

using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace com::sun::star::bridge;
using namespace com::sun::star::frame;
using namespace com::sun::star::registry;

If anything is missing, the compiler will tell you about it.

This concludes this article about getting started with integrating LibreOffice SDK into C++ and Visual Studio. Next is about actually doing integration work and what errors you may encounter in the process.

Comments

  1. Pavel October 19, 2016 Leave a Reply

    Thank you for the great article. This was incredibly useful and well written! A am currently fighting with LibreOffice sdk for 3 days in a row, trying to make it work even with simplest code and no success yet. Really looking forward to see the sequel.

    • Kent Fagerjord October 19, 2016 Leave a Reply

      Hi Pavel,

      Thank you for the kind words!

      I’ve struggled some days to actually get the LibreOffice SDK to talk to LibreOffice Calc. Even inserting text into cells seemed “impossible” at some point, due to numerous errors. But I managed to insert some text into some cells and the sequel is just hours away.

      Kent

  2. Pavel October 19, 2016 Leave a Reply

    That is very unfortunate. I am searching for a way to somehow embed office spreadsheets into Qt application forms and i thought that working with LibreOffice api would be the simplest solution. Have you tried to do something like this?

    • Kent Fagerjord October 19, 2016 Leave a Reply

      I haven’t tried to embed LibreOffice into Qt. Maybe that’s a project for the future.

      At the moment I’m only “commanding” LibreOffice Calc to do stuff from a command line application.

      Are you targeting Windows or Linux?

      For embedding I would presume there is something in the UNO bridge that tells LibreOffice to paint itself on your Qt controls. As far as I know, UNO and COM are similar. Maybe you can find something similar with COM and MS Office where Excel is painted on a Qt control?

      Kent

  3. Pavel October 20, 2016 Leave a Reply

    I am targeting both Windows and Linux. And that itself of course make things hard, i can not use COM\ActiveX. Thanks you for your reply, i will continue digging LibreOffice and if that fails i ll try my luck with OnlyOffice api. That looks interesting as well.

  4. Warren November 8, 2016 Leave a Reply

    Thank you for this tutorial.

    As a neophyte, I guess i was having particular trouble getting the header generation to work. I tested my PATH which was correct, but eventually gave up and ended up copying six .dlls into my C:\Windows directory. After I jury rigged that, I discovered cppumaker didn’t like spaces in my directory names even having surrounded them in quotes (I should have known), though correcting that still didn’t help with the .dlls.

    But, with your help I made it through that task. I learned a lot. I’m just curious why these files wouldn’t have been included with the SDK download? They seem pretty essential. Again thank you for your post. It was very timely for my little project.

Leave a Reply


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*