首页 文章

从LibreOffice Basic调用C共享库函数

提问于
浏览
0

我正在尝试从LibreOffice Basic调用C共享库函数,但是当它到达Declare行时,我总是得到“基本运行时错误 . 未实现” . 这只是为了一个有趣的事情,但无法做到这一点是困扰我 .

Declare语句如下所示:

Declare Function score_word Lib "libscrabblescore.so" (ByRef word As String, ByRef bonus As String) As Integer

C函数delaration如下所示:

int score_word(char* word, char* word_bonuses)

(也许ByRef word As String不是char * word的正确翻译?我找不到关于如何将char *参数用于LibreOffice Basic函数的文档 . )

我通过使用Python的ctypes模块调用它来验证共享库本身:

>>> from ctypes import CDLL
>>> lib = CDLL("/usr/lib/libscrabblescore.so")
>>> lib.score_word("qi", "dw dlq")
42
>>>

(所以我有“回答生命,宇宙和一切的终极问题”,而不是在LibreOffice Basic中如何做到这一点!)

我也尝试在Declare语句中使用绝对路径,但没有区别 .

我发现了一个关于调用DLL的主题的Windows线程,其中提问者说他需要将DLL放在特定位置(LibreOffice bin目录),以便LibreOffice可以访问它 . Linux上没有LibreOffice bin目录,不幸的是我的机器上有351个候选目录(我的路径,名称中包含“libreoffice”的所有文件夹或“libreoffice”文件夹下的所有文件夹)名字) .

我尝试了一种霰弹枪方法并在所有351个目录中放置了一个符号链接到共享库,但随后Calc在启动时挂起 . 所以我删除了那些,开始计算,并将它们全部放回原位并尝试了该功能 . 如果它是一个位置的东西,你会认为这将起作用,因为LibreOffice Basic应该在Declare点加载库 . 仍然没有运气 .

在oooforums上有一些看起来很有希望,但是当我尝试查看该主题时,该网站会超时 . (编辑:今晚我设法查看了该主题,这是Windows安全问题 . 我关闭了LibreOffice中的所有宏安全性,但仍然存在问题 . )

那么,有没有人从LibreOffice Basic程序成功调用C共享库函数,该程序知道我做错了什么?谢谢!

2 回答

  • 0

    乔纳森莱因哈特是正确的;用于调用共享库的“Declare”命令在Windows上实现,但在Linux上不实现 . 由于在博客文章中引用了关于此事的OpenOffice错误报告,我只能验证这一点 .

    我第一次尝试解决方案是重写LibreOffice Basic中的函数 . 它工作,但最多需要3秒才能返回结果 .

    我考虑放弃并离开它,但是等待三秒钟太不愉快了 . 我研究了如何通过UNO实现一个C函数,这对于一个相当简单的任务来说过于复杂 .

    最后我做的是写一个仍然给出“即时”结果的kludge(每个函数调用大约0.025秒) .

    我将DLL重写为C控制台应用程序,它接受命令行参数并将结果写入临时文件 . 然后我用一个函数替换了我的LibreOffice Basic代码,该函数使用Shell以阻塞模式调用C控制台应用程序,并从文件中检索结果 . 这很丑陋,但它不是一个多用户的东西,它的工作原理 .

    如果有人自己遇到这个问题,这里是我用过的LibreOffice Basic代码 - 这很简单 .

    option explicit
    
    function scorewords(wordlist as string, bonuslist as string) as integer
       dim cparams as string
       dim fileno as integer
       dim results_file as string
       dim score as integer
    
       if wordlist = "" then
           scorewords = 0
           exit function
       end if
    
       cparams = """" + wordlist + """" + " " + """" + bonuslist + """"
       results_file = "/tmp/scrabblescore.dat"
       Shell("/usr/bin/getscrabblescore", 6, cparams, true)
    
       fileno = freefile
       open results_file for input as fileno
       input #fileno, score
       close #fileno
    
       kill results_file
    
       scorewords = score
    end function
    
  • 0

    除非您仅限于Basic,否则看起来您的问题已经显示出一个很好的解决方案 . 在Python UNO中写这样的东西:

    import ctypes
    lib = ctypes.cdll.loadLibrary("/usr/lib/libscrabblescore.so")
    result = lib.score_word("qi", "dw dlq")
    oText.insertString(oTextCursor, result, 0)
    

相关问题