从LibreOffice Basic调用C共享库函数

时间:2014-06-22 17:40:56

标签: c shared-libraries libreoffice-calc libreoffice-basic

我试图从LibreOffice Basic调用C共享库函数,但我总是得到"基本运行时错误。未实施"当它击中声明线。它只是为了一个有趣的事情,但无法做到这一点是困扰我。

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
>>> 

(所以我有#34;回答生命,宇宙和一切的终极问题,"只是没有在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 :(得分:0)

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

我首次尝试解决方案是重写LibreOffice Basic中的函数。它有效,但最多需要3秒才能恢复结果。

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

最后我做的是写一个仍然给出"即时"结果(每个函数调用大约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

答案 1 :(得分: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)