Errors connecting to LibreOffice with C++, part 2

By , last updated December 2, 2019

In part 1, we started the integration of LibreOffice into C++. This is part 2 where the errors of connecting to LibreOffice are discussed and resolved.

Having the headers generated from part 1 is a requirement and is not optional!

When doing integration between C++ and LibreOffice through the Uno bridge, I encountered a couple of problems.

css::uno::DeploymentException

The debugger is quick to come with this error, and not much else. You have to have the code in a try-catch clause to actually see the error.

The first errors were easily solved, however, I used a couple of days solving the last error with stack overflow in msci_uno.dll.

catch (Exception & e)
{
	fprintf(stderr, "caught UNO exception: %s\n",
		OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US).getStr());
	return 1;
}

It will reveal the program can’t load and find uno.ini.

Error: cannot establish a connection using 'uno:socket,host=localhost,port=2083;urp;StarOffice.ServiceManager':
Cannot open uno ini file:///R:/crossword-gen/run/uno.ini

Uno.ini can be found in the programs folder in the LibreOffice installation. With the default installation directory on Windows, it’ll be C:\Program Files (x86)\LibreOffice 5\program. It is not necessary to edit uno.ini.

Set the program to start in the programs directory of LibreOffice using the Working Directory under Debugging in Visual Studio.

libreoffice-running-directory

WSAECONNREFUSED, Connection refused

Error: Connector : couldn't connect to socket (WSAECONNREFUSED, Connection refused)

The soffice server service isn’t started. Start it with:

rem start_soffice_server.bat
set LIBRE=C:\Program Files (x86)\LibreOffice 5\program
set PATH=%LIBRE%;%PATH%

soffice "--accept=socket,host=localhost,port=2083;urp;StarOffice.ServiceManager"

Save this code in a file called start_soffice_server.bat and run it. It can run as a regular user.

Later in this post I’ll write how to create a bridge without having a listening socket.

WSANOTINITIALISED, WSAStartup() has not been called

Error: cannot establish a connection using 'uno:socket,host=localhost,port=2083;urp;StarOffice.ServiceManager':
Connector : couldn't connect to socket (WSANOTINITIALISED, WSAStartup() has not been called)

WSANOTINITIALISED is an error that comes from the Windows Sockets subsystem. It’s because the application tried to use sockets before they are initialized. It is easily mitigated by initializing Winsockets before trying to connect to the LibreOffice server.

Create a method called initWSA() or thereof.

void initWSA()
{
	auto wVersionRequested = MAKEWORD(2, 2);
	WSADATA wsaData;

	if (WSAStartup(wVersionRequested, &wsaData))
	{
		return; // winsock dll couldn't be loaded
	}
}

Call this method before trying to connect to the LibreOffice server. To build you must link against Ws2_32.lib. The dirtiest and easiest way to link is putting this pragma directive at the top of the .cpp-file.

#pragma comment(lib, "Ws2_32.lib")

It is Windows and Visual Studio only, and this is a problem only with Windows. And it’s probably a bug in the SDK.

NoSuchElementException and 0xC00000FD: Stack overflow

The crux of the matter.

When following the tutorials you will encounter this error with recent versions of the LibreOffice suite and SDK.

It happens when trying to create a document object, in which you want to modify programmatically. It also happens to be the common denominator for all LibreOffice document types (Writer, Calc, Impress).

The common error happens when trying to load com.sun.star.frame.Desktop through the UNO bridge. Here is an example code for crashing the UNO bridge:

Reference<XInterface> rDesktop = rOfficeServiceManager->createInstance(
	OUString::createFromAscii("com.sun.star.frame.Desktop"));

// Stack overflow crash here
Reference< XComponentLoader > mComponentLoader(rDesktop, UNO_QUERY);

These two errors occur in tandem. While the output window in Visual Studio keeps filling up with com::sun::star::container::NoSuchElementException and after a couple of seconds it crashes with 0xC00000FD: Stack overflow.

The exception is not propagated to user code, so it means the exception is handled in the SDK. However, the stack overflow runtime error is very much real and will crash your application.

Errors when trying to load com.sun.star.frame.Desktop through a socket UNO bridge. The runtime error occurs in msci_uno.dll.

Exception thrown at 0x779196C2 in crossword-gen.exe: Microsoft C++ exception: com::sun::star::container::NoSuchElementException at memory location 0x006FE5B0.
Exception thrown at 0x779196C2 in crossword-gen.exe: Microsoft C++ exception: com::sun::star::container::NoSuchElementException at memory location 0x006FE5B0.
Exception thrown at 0x02894574 (msci_uno.dll) in crossword-gen.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x00602FFC).
Unhandled exception at 0x02894574 (msci_uno.dll) in crossword-gen.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x00602FFC).

I haven’t been able to resolve this particular error, but I’ve been able to open up LibreOffice Calc and insert text into cells by doing things just a little bit differently.