【问题标题】:Calling C shared library function from LibreOffice Basic从 LibreOffice Basic 调用 C 共享库函数
【发布时间】:2014-06-22 17:40:56
【问题描述】:

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

Declare 语句如下所示:

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

C 函数声明如下所示:

int score_word(char* word, char* word_bonuses)

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

我通过使用 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 在启动时挂起。所以我删除了这些,启动了 Calc,然后将它们全部放回原位并尝试了该功能。如果是位置问题,您会认为 LibreOffice Basic 应该在声明点加载库。还是没有运气。

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

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

【问题讨论】:

  • "Not implemented" 听起来您尝试使用的功能不存在。
  • 我很确定这意味着共享库函数被认为是“未实现”,因为找不到它。
  • @ReeseCurrie Totaly 同意你的观点,只是遇到了和你一样的问题。您是否设法在此期间解决了您的问题?
  • Jonathon 是正确的,有一段时间我使用了下面 1 个答案中的代码。最终,我将我在 Python 中所做的事情重写为 .oxt OpenOffice 扩展。
  • @ReeseCurrie Jonathan 告诉我们“您尝试使用的功能不存在”。我不太明白他的意思是什么,但我真的认为,正如你所做的那样,共享库函数被认为是“未实现”,因为它找不到。 (其实我和你一样,但是在mac os x上,没有任何问题,当我切换到linux时也和你一样。)

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


【解决方案1】:

乔纳森·莱因哈特是正确的;用于调用共享库的“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

【讨论】:

    【解决方案2】:

    除非您仅限于 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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-02
      • 2023-03-11
      • 2021-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多