帮助诊断使用 C++ Ubuntu 14.04.01 LTS 服务器开发自定义 OpenOffice 4.1 应用程序中的问题

帮助诊断使用 C++ Ubuntu 14.04.01 LTS 服务器开发自定义 OpenOffice 4.1 应用程序中的问题

我寻求有关我们的 C++ 电子表格服务器应用程序的“通用”部分的帮助,该应用程序连接到无头 Open Office 4.1.2 服务。

此应用程序的“通用”连接部分如下所示。我们确实需要 XDesktop 和 XComponentLoader 功能才能工作,但它们给我们带来了问题,即使独立运行时也是如此。

我们是否正确使用了这些功能?我们如何让它们发挥作用,或者有什么更好的替代方案?

代码(OpenOffice example.cxx):

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <cppuhelper/bootstrap.hxx>
#include <com/sun/star/bridge/XUnoUrlResolver.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/uno/XInterface.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/document/XTypeDetection.hpp>

using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::bridge;
using namespace com::sun::star::beans;
using namespace com::sun::star::frame;
using namespace com::sun::star::container;
using namespace com::sun::star::document;
using namespace rtl;
using namespace cppu;

#define DIAG(s) printf("%s\n",s)
#define OOCHECKREF(x) if (!x.is()){printf("Error: "#x"\n");return 1;}

int main (int argc, char *argv[]) {
   try {
     DIAG("mComponentContext");
     Reference< XComponentContext > mComponentContext
         = defaultBootstrap_InitialComponentContext();

     DIAG("mServiceManager");
     Reference< XMultiComponentFactory > mServiceManager
         = mComponentContext->getServiceManager();

     DIAG("rResolverInstance");
     Reference< XInterface > rResolverInstance
         = mServiceManager->createInstanceWithContext (
             OUString::createFromAscii(
                 "com.sun.star.bridge.UnoUrlResolver") ,
     mComponentContext);

     DIAG("rResolver");
     Reference< XUnoUrlResolver > rResolver (rResolverInstance,
                                             UNO_QUERY);
     OOCHECKREF(rResolver)

     DIAG("rOfficeInstance");    
     Reference< XInterface > rOfficeInstance
         = rResolver->resolve (
             OUString::createFromAscii
                ("uno:socket,host=localhost,port=8199;    
                       urp;StarOffice.ServiceManager")) ;
     OOCHECKREF(rOfficeInstance)

     DIAG("rOfficeServiceManager");
     Reference< XMultiServiceFactory > rOfficeServiceManager (
         rOfficeInstance, UNO_QUERY);
     OOCHECKREF(rOfficeServiceManager)

     DIAG("xPropSet");
     Reference< XPropertySet > xPropSet (rOfficeInstance, UNO_QUERY) ;
     xPropSet->getPropertyValue (
          OUString::createFromAscii("DefaultContext")) 
             >>= mComponentContext;

     DIAG("xMultiComponentFactoryServer");
     Reference< XMultiComponentFactory > xMultiComponentFactoryServer(
         mComponentContext->getServiceManager());

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

     DIAG("mComponentLoader");
     Reference< XComponentLoader > mComponentLoader (rDesktop,  
                                                     UNO_QUERY);
     OOCHECKREF(mComponentLoader)

     DIAG("rFiltersInt");
     Reference< XInterface > rFiltersInt 
         = rOfficeServiceManager->createInstance(
             OUString::createFromAscii(
                 "com.sun.star.document.FilterFactory"));
     OOCHECKREF(rFiltersInt)

     DIAG("mFilterFactory");
     Reference<XNameAccess> mFilterFactory
         = Reference< XNameAccess (rFiltersInt, UNO_QUERY);
     OOCHECKREF(mFilterFactory)

     DIAG("rTypeDetectInt");
     Reference< XInterface > rTypeDetectInt 
         = rOfficeServiceManager->createInstance(
            OUString::createFromAscii(
                "com.sun.star.document.TypeDetection"));
     OOCHECKREF(rTypeDetectInt)

     DIAG("mTypeDetect");
     Reference< XTypeDetection > mTypeDetect 
         = Reference< XTypeDetection  (rTypeDetectInt, UNO_QUERY);
     OOCHECKREF(mTypeDetect)

     DIAG ("Connected successfully to the office - press enter to exit");
     getchar();
   } catch (Exception &e) {
     OString o = OUStringToOString (e.Message,   
                                    RTL_TEXTENCODING_ASCII_US);
     printf ("Error: %s\n", o.pData->buffer);
     return 1;
  }
  return 0;
}

存在哪些问题?

下面的代码可以编译、运行和连接,但是在最后一次按键之后(getchar()之后)会出现段错误:

gdb ../../../LINUXexample.out/bin/ooexample
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ../../../LINUXexample.out/bin/ooexample...(no debugging symbols found)...done.
(gdb) r
Starting program: /opt/libreoffice5.2/sdk/LINUXexample.out/bin/ooexample
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
mComponentContext
[New Thread 0x7ffff5988700 (LWP 12125)]
mServiceManager
rResolverInstance
rResolver
rOfficeInstance
[New Thread 0x7ffff4015700 (LWP 12128)]
[New Thread 0x7ffff3814700 (LWP 12129)]
rOfficeServiceManager
xPropSet
xMultiComponentFactoryServer
rDesktop
mComponentLoader
rFiltersInt
mFilterFactory
rTypeDetectInt
mTypeDetect
Connected successfully to the office - press enter to exit

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff489b723 in cpp_vtable_call ()
   from /opt/libreoffice5.2/program/libgcc3_uno.so
(gdb) bt
#0  0x00007ffff489b723 in cpp_vtable_call ()
   from /opt/libreoffice5.2/program/libgcc3_uno.so
#1  0x00007ffff48a26ea in privateSnippetExecutor ()
   from /opt/libreoffice5.2/program/libgcc3_uno.so
#2  0x0000000000401ea9 in main ()
(gdb) c
Continuing.
[Thread 0x7ffff7fc8780 (LWP 11222) exited]
[Thread 0x7ffff4015700 (LWP 11229) exited]
[Thread 0x7ffff5988700 (LWP 11226) exited]

Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.

为什么特别选择 XDesktop 和 XComponentLoader?

我们发现,如果不事先调用这些功能,电子表格 API 的调用似乎不起作用,如代码示例所示。完整应用程序中嵌入的相同代码以及一个有点类似的示例都在 XComponentLoader 调用中失败(回溯终止于该行)。因此,我们怀疑 XComponentLoader 存在问题。

我们已经尝试使用 Libreoffice 4 SDK(根据 ubuntu trusty repo)、Libreoffice 5.2 SDK 和 Openoffice 4.1.2 SDK,结果相同。

我们遵循了什么例子?

首先我们开始https://wiki.openoffice.org/wiki/Documentation/DevGuide/ProUNO/C%2B%2B/Establishing_Interprocess_Communications然后使用我们应用程序代码的先前版本添加 XDesktop 和 XComponentLoader 引用。(此先前版本在引导阶段失败,使用了已淘汰的 cppu::createSimpleRegistry 调用,现在导致程序中止,请参阅https://docs.libreoffice.org/cppuhelper/html/compat_8cxx_source.html,第 80 行以上)。如上所述,在完整应用程序中运行上述代码会在 XComponentLoader 阶段发生段错误。

所提及的“类似”示例来自 www.linuxjournals.com/article/8608#。在 xComponentLoader->loadComponentFromURL 调用处发生执行段错误(回溯终止于该行;传入该方法的文件和目录参数在检查时看起来不错;标志为 0,属性序列为空)。

相关内容