#c #shared-libraries #libreoffice-calc #libreoffice-basic
#c #разделяемые библиотеки #libreoffice-calc #libreoffice-basic
Вопрос:
Я пытаюсь вызвать функцию общей библиотеки C из LibreOffice Basic, но я всегда получаю «Основную ошибку времени выполнения. Не реализовано», когда он попадает в строку объявления. Это просто для развлечения, но неспособность это сделать меня беспокоит.
Оператор 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 Как String не является правильным переводом char * word? Я не могу найти документацию о том, как использовать параметры char * для функций из LibreOffice Basic.)
Я проверил саму разделяемую библиотеку, вызвав ее с помощью модуля ctypes Python:
>>> from ctypes import CDLL
>>> lib = CDLL("/usr/lib/libscrabblescore.so")
>>> lib.score_word("qi", "dw dlq")
42
>>>
(Итак, у меня есть «Ответ на главный вопрос жизни, Вселенной и всего остального», только не о том, как это сделать в LibreOffice Basic!)
Я также попытался использовать абсолютный путь в инструкции Declare, и это не имело никакого значения.
Я нашел ветку Windows на тему вызова DLL, где запрашивающий сказал, что ему нужно поместить DLL в определенное место (каталог LibreOffice bin), чтобы LibreOffice мог получить к нему доступ. В Linux нет каталога LibreOffice bin как такового, и, к сожалению, на моем компьютере есть 351 каталог-кандидат, который я смог идентифицировать (мой путь и все папки с «libreoffice» в имени или в папке с «libreoffice» в имени).
Я попробовал подход с дробовиком и поместил символическую ссылку на разделяемую библиотеку во все 351 каталог, но затем Calc зависает при запуске. Итак, я удалил их, запустил Calc, вернул их все на место и попробовал функцию. Если бы это было связано с местоположением, вы бы подумали, что это сработает, поскольку LibreOffice Basic должен загружать библиотеку в момент объявления. Все еще не повезло.
На oooforums было что-то многообещающее, но время ожидания сайта истекает, когда я пытаюсь просмотреть поток. (РЕДАКТИРОВАТЬ: мне удалось просмотреть поток сегодня вечером, и это была проблема безопасности Windows. Я отключил всю защиту макросов в своем LibreOffice, и проблема все еще остается.)
Итак, кто-нибудь когда-либо успешно вызывал функцию общей библиотеки C из программы LibreOffice Basic, которая знает, что я делаю неправильно? Спасибо!
Комментарии:
1.
"Not implemented"
похоже, что функция, которую вы пытаетесь использовать, не существует.2. Я почти уверен, что это означает, что функция общей библиотеки считается «Не реализованной», поскольку ее не удалось найти.
3. @ReeseCurrie Полностью согласен с вами, просто столкнулся с той же проблемой, что и у вас. Удалось ли вам решить вашу проблему в meantine?
4. Джонатан был прав, некоторое время я использовал код в приведенном ниже ответе 1. В конечном итоге я переписал то, что я делал на Python, как расширение OpenOffice .oxt.
5. @ReeseCurrie Джонатан сказал, что «функция, которую вы пытаетесь использовать, не существует». Я не совсем хорошо понимаю, что он имел в виду под этим, но я действительно думаю, как и вы, что функция разделяемой библиотеки считается «Не реализованной», потому что ее не удалось найти. (На самом деле, я делал то же самое, что и вы, но на mac os x, без каких-либо проблем, и у меня была та же проблема, что и у вас, когда я переключился на Linux.)
Ответ №1:
Джонатон Рейнхарт прав; команда «Объявить» для вызова разделяемых библиотек реализована в Windows, но не в Linux. Я смог проверить это только из-за ссылки на отчет об ошибке OpenOffice по этому вопросу в сообщении в блоге.
Моей первой попыткой решения было переписать функцию в LibreOffice Basic. Это сработало, но для возврата результатов потребуется до 3 секунд.
Я подумывал о том, чтобы сдаться и оставить все как есть, но было слишком неприятно ждать три секунды. Я изучил, как реализовать функцию C через UNO, которая была слишком сложной для довольно тривиальной задачи.
Наконец, что я сделал, так это написал kludge, который по-прежнему дает «мгновенные» результаты (около 0,025 секунды при каждом вызове функции).
Я переписал DLL как консольное приложение на C , которое принимает аргументы командной строки и записывает результат во временный файл. Затем я заменил свой код LibreOffice Basic функцией, которая вызывает консольное приложение C в режиме блокировки с помощью оболочки и извлекает результаты из файла. Это некрасиво, но это не многопользовательская вещь, и она работает.
На случай, если кто-нибудь сам столкнется с этой проблемой, вот базовый код LibreOffice, который я использовал для этого — он очень прост.
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)