请选择 进入手机版 | 继续访问电脑版

LibreOffice 中文社区

 找回密码
 马上加入

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
开启左侧

vs2010 搭建libreoffice 中SDK中的DocumentLoader例子

[复制链接]
shc-2021 发表于 2021-7-15 18:17:15 | 显示全部楼层 |阅读模式
问题描述:     C++ 的sdk 的头文件都生成了,环境也搭建好了,直接用的是w32的控制台程序。复制了DocumentLoader例子的代码,编译成功了,运行报错。

重现步骤:     复制了DocumentLoader例子的代码,编译成功了,运行报错。

当前的行为和结果:
      Error: cannot establish a connection using 'uno:socket,host=localhost,port=2083;urp;StarOffice.ServiceManager':       loading component library </mergedlo.dll> failed

期望的行为和结果:

操作系统和软件版本:

用于测试的附件(非必须):


高原之狼 发表于 2021-7-16 07:47:03 | 显示全部楼层
楼主在官方开发者邮件列表也发了求助邮件:
https://lists.freedesktop.org/ar ... 21-July/087617.html

(但是说实话这求助邮件水平很低,甚至还不如这个中文求助贴里的信息全面。再加上 Windows 操作系统类型和版本,LibreOffice 版本,如何安装的 SDK 等等都不说,别人是很难帮忙的。)
 楼主| shc-2021 发表于 2021-7-15 18:17:51 | 显示全部楼层
try
    {
        xInterface = Reference< XInterface >(
            resolver->resolve(sConnectionString), UNO_QUERY);
    }
    catch (Exception& e)
    {
        printf("Error: cannot establish a connection using '%s':\n       %s\n",
            OUStringToOString(sConnectionString, RTL_TEXTENCODING_ASCII_US).getStr(),
            OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US).getStr());

        exit(1);
    }
 楼主| shc-2021 发表于 2021-7-15 18:28:11 | 显示全部楼层

VS2019 SDK 运行报错loading component library </mergedlo.dll> failed


代码:
try
    {
        xInterface = Reference< XInterface >(
            resolver->resolve(sConnectionString), UNO_QUERY);
    }
    catch (Exception& e)
    {
        printf("Error: cannot establish a connection using '%s':\n       %s\n",
            OUStringToOString(sConnectionString, RTL_TEXTENCODING_ASCII_US).getStr(),
            OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US).getStr());

        exit(1);
    }

报错信息:
Error: cannot establish a connection using 'uno:socket,host=localhost,port=2083;urp;StarOffice.ServiceManager':
       loading component library </mergedlo.dll> failed


 楼主| shc-2021 发表于 2021-7-16 14:11:15 | 显示全部楼层
高原之狼 发表于 2021-7-16 07:47
楼主在官方开发者邮件列表也发了求助邮件:
https://lists.freedesktop.org/archives/libreoffice/2021-Jul ...

你每天都在说假话吗?不知道就不知道 BBBBB 有意思?
 楼主| shc-2021 发表于 2021-7-16 17:44:13 | 显示全部楼层
报错Error: loading component library </mergedlo.dll> failed,感觉是libreoffice源码里面加载找个dll的时候前面多加了个'/' ?
我写了个测试例子加载这个dll 成功
HMODULE dlhandle = LoadLibraryA("mergedlo.dll");
    if (!dlhandle)
    {
        printf("LoadLibraryA error! \n");
    }
我看了这个dll就在LibreOffice的安装目录下\program,而且我把路径加入到环境变量PTAH中了,加载的时候会根据路径查询。
你们都没遇到这种问题吗?
 楼主| shc-2021 发表于 2021-7-16 17:47:56 | 显示全部楼层
而且libreoffice 源码里面搜加载mergedlo.dll 也就在LibreOfficeKitInit.h 这个文件里有用到。
但是sdk中不知道啥时间会调用这个?

#else
    #if !defined WIN32_LEAN_AND_MEAN
        #define WIN32_LEAN_AND_MEAN
    #endif
    #include  <windows.h>
    #define TARGET_LIB        "sofficeapp" ".dll"
    #define TARGET_MERGED_LIB "mergedlo" ".dll"
    #define SEPARATOR         '\\'
    #define UNOPATH           "\\..\\URE\\bin"

    static void *lok_loadlib(const char *pFN)
    {
        return (void *) LoadLibraryA(pFN);
    }

    static char *lok_dlerror(void)
    {
        LPSTR buf = NULL;
        FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL, GetLastError(), 0, reinterpret_cast<LPSTR>(&buf), 0, NULL);
        return buf;
    }

    // This function must be called to release memory allocated by lok_dlerror()
    static void lok_dlerror_free(char *pErrMessage)
    {
        HeapFree(GetProcessHeap(), 0, pErrMessage);
    }

    static void *lok_dlsym(void *Hnd, const char *pName)
    {
        return reinterpret_cast<void *>(GetProcAddress((HINSTANCE) Hnd, pName));
    }

    static int lok_dlclose(void *Hnd)
    {
        return FreeLibrary((HINSTANCE) Hnd);
    }

    static void extendUnoPath(const char *pPath)
    {
        char *sNewPath = NULL, *sEnvPath = NULL;
        size_t size_sEnvPath = 0, buffer_size = 0;
        DWORD cChars;

        if (!pPath)
            return;

        cChars = GetEnvironmentVariableA("PATH", sEnvPath, 0);
        if (cChars > 0)
        {
            sEnvPath = (char *) malloc(cChars);
            cChars = GetEnvironmentVariableA("PATH", sEnvPath, cChars);
            //If PATH is not set then it is no error
            if (cChars == 0 && GetLastError() != ERROR_ENVVAR_NOT_FOUND)
            {
                free(sEnvPath);
                return;
            }
        }
        //prepare the new PATH. Add the Ure/bin directory at the front.
        //note also adding ';'
        if(sEnvPath)
            size_sEnvPath = strlen(sEnvPath);
        buffer_size = size_sEnvPath + 2*strlen(pPath) + strlen(UNOPATH) + 4;
        sNewPath = (char *) malloc(buffer_size);
        sNewPath[0] = L'\0';
        strcat_s(sNewPath, buffer_size, pPath);     // program to PATH
        strcat_s(sNewPath, buffer_size, ";");
        strcat_s(sNewPath, buffer_size, UNOPATH);   // UNO to PATH
        if (size_sEnvPath > 0)
        {
            strcat_s(sNewPath, buffer_size, ";");
            strcat_s(sNewPath, buffer_size, sEnvPath);
        }

        SetEnvironmentVariableA("PATH", sNewPath);

        free(sNewPath);
        free(sEnvPath);
    }
#endif

#if !defined(IOS)
static void *lok_dlopen( const char *install_path, char ** _imp_lib )
{
    char *imp_lib;
    void *dlhandle;

    size_t partial_length, imp_lib_size;
    struct stat dir_st;

    *_imp_lib = NULL;

    if (!install_path)
        return NULL;

    if (stat(install_path, &dir_st) != 0)
    {
        fprintf(stderr, "installation path \"%s\" does not exist\n", install_path);
        return NULL;
    }

    // allocate large enough buffer
    partial_length = strlen(install_path);
    imp_lib_size = partial_length + sizeof(TARGET_LIB) + sizeof(TARGET_MERGED_LIB) + 2;
    imp_lib = (char *) malloc(imp_lib_size);
    if (!imp_lib)
    {
        fprintf( stderr, "failed to open library : not enough memory\n");
        return NULL;
    }

    memcpy(imp_lib, install_path, partial_length);

    extendUnoPath(install_path);

    imp_lib[partial_length++] = SEPARATOR;
    strncpy(imp_lib + partial_length, TARGET_LIB, imp_lib_size - partial_length);

    dlhandle = lok_loadlib(imp_lib);
    if (!dlhandle)
    {
        // If TARGET_LIB exists, and likely is a real library (not a
        // small one-line text stub as in the --enable-mergedlib
        // case), but dlopen failed for some reason, don't try
        // TARGET_MERGED_LIB.
        struct stat st;
        if (stat(imp_lib, &st) == 0 && st.st_size > 100)
        {
            char *pErrMessage = lok_dlerror();
            fprintf(stderr, "failed to open library '%s': %s\n",
                    imp_lib, pErrMessage);
            lok_dlerror_free(pErrMessage);
            free(imp_lib);
            return NULL;
        }

        strncpy(imp_lib + partial_length, TARGET_MERGED_LIB, imp_lib_size - partial_length);

        dlhandle = lok_loadlib(imp_lib);
        if (!dlhandle)
        {
            char *pErrMessage = lok_dlerror();
            fprintf(stderr, "failed to open library '%s': %s\n",
                    imp_lib, pErrMessage);
            lok_dlerror_free(pErrMessage);
            free(imp_lib);
            return NULL;
        }
    }
    *_imp_lib = imp_lib;
    return dlhandle;
}
#endif
 楼主| shc-2021 发表于 2021-7-16 17:50:28 | 显示全部楼层
源码中搜到用到mergedlo.dll,也就在LibreOfficeKitInit.h 文件中,但是sdk 会在什么时间调用这玩意?

#if !defined WIN32_LEAN_AND_MEAN
        #define WIN32_LEAN_AND_MEAN
    #endif
    #include  <windows.h>
    #define TARGET_LIB        "sofficeapp" ".dll"
    #define TARGET_MERGED_LIB "mergedlo" ".dll"
    #define SEPARATOR         '\\'
    #define UNOPATH           "\\..\\URE\\bin"

    static void *lok_loadlib(const char *pFN)
    {
        return (void *) LoadLibraryA(pFN);
    }
 楼主| shc-2021 发表于 2021-7-16 17:52:02 | 显示全部楼层
有大神熟悉libreoffice 的代码结构和调用流程的?留个联系方式交流下,重金感谢。
suokunlong 发表于 2021-7-17 19:39:59 | 显示全部楼层
无意间看到了这个帖子。楼主可能把DocumentLoader的例子没有看完整,没有理解。你的Loader程序要与LibreOffice交互,那么 LibreOffice 必须是活的喘气的才行啊。
也就是说,在运行你的Loader程序之前,你必须首先启动 LibreOffice 让其监听相应的端口:
[Bash shell] 纯文本查看 复制代码
<LibreOffice程序路径>/program/soffice "--accept=socket,port=2083;urp;"


楼主的错误提示里也说的很明白,cannot establish a connection using 'uno:socket,host=localhost,port=2083;urp;StarOffice.ServiceManager'.

参考刚刚有人提交的一个Python的DocumentLoader的 Demo,里面有个README有用法说明:
https://git.libreofficechina.org ... 825173075cd938a230c
开放,包容,奉献。
*滑块验证:
您需要登录后才可以回帖 登录 | 马上加入

本版积分规则

Archiver|手机版|小黑屋|LibreOffice 中文社区 ( 粤ICP备13080851号-4 )

GMT+8, 2021-8-2 09:52

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表