Java, панама проекта и как работать с результатом «предложения» Hunspell
Я экспериментирую с Hunspell и взаимодействую с ним с помощью Java Project Panama (сборка 19-panama+1-13 (2022/1/18)). Мне удалось провести начальное тестирование, например, при создании
public class HelloHun {
public static void main(String[] args) {
MemoryAddress hunspellHandle = null;
try (ResourceScope scope = ResourceScope.newConfinedScope()) {
var allocator = SegmentAllocator.nativeAllocator(scope);
// Point it to US english dictionary and (so called) affix file
// Note #1: it is possible to add words to the dictionary if you like
// Note #2: it is possible to have separate/individual dictionaries and affix files (e.g. per user/doc type)
var en_US_aff = allocator.allocateUtf8String("/usr/share/hunspell/en_US.aff");
var en_US_dic = allocator.allocateUtf8String("/usr/share/hunspell/en_US.dic");
// Get a handle to the Hunspell shared library and load up the dictionary and affix
hunspellHandle = Hunspell_create(en_US_aff, en_US_dic);
// Feed it a wrong word
var javaWord = "koing";
// Do a simple spell check of the word
var word = allocator.allocateUtf8String(javaWord);
var spellingResult = Hunspell_spell(hunspellHandle, word);
System.out.println(String.format("%s is spelled %s", javaWord, (spellingResult == 0 ? "incorrect" : "correct")));
// Hunspell also supports giving suggestions for a word - which is what we do next
// Note #3: by testing this `koing` word in isolation - we know that there are 4 alternatives for this word
// Note #4: I'm still investigating how to access individual suggestions
var suggestions = allocator.allocate(10);
var suggestionCount = Hunspell_suggest(hunspellHandle, suggestions, word);
System.out.println(String.format("There are %d suggestions for %s", suggestionCount, javaWord));
// `suggestions` - according to the hunspell API - is a `pointer to an array of strings pointer`
// we know how many `strings` pointer there are, as that is the returned value from `suggest`
// Question: how to process `suggestions` to get individual suggestions
} finally {
if (hunspellHandle != null) {
Hunspell_destroy(hunspellHandle);
}
}
}
}
Я вижу, что вызов
Что для меня сейчас более сложно, так это то, как мне распаковать
Итак, по сути, вот мой вопрос:
Как распаковать структуру, которая, как сообщается, состоит из указателя на массив строк, указывающих с помощью API Panama JDK19 на соответствующую коллекцию строк?
1 ответ
Глядя на заголовок здесь: https://github.com/hunspell/hunspell/blob/master/src/hunspell/hunspell.h#L80
/* suggest(suggestions, word) - search suggestions
* input: pointer to an array of strings pointer and the (bad) word
* array of strings pointer (here *slst) may not be initialized
* output: number of suggestions in string array, and suggestions in
* a newly allocated array of strings (*slts will be NULL when number
* of suggestion equals 0.)
*/
LIBHUNSPELL_DLL_EXPORTED int Hunspell_suggest(Hunhandle* pHunspell,
char*** slst,
const char* word);
The
slst
является классическим «выходным» параметром. т.е. мы передаем указатель на некоторое значение (в данном случае это массив строк), и функция установит этот указатель для нас, как способ вернуть несколько результатов. (первым результатом является количество предложений)
В панаме вы используете параметры «out», выделяя сегмент с макетом типа, на который параметр является указателем. В таком случае
char***
является указателем на
char**
, так что макет
ADDRESS
. Затем мы передаем созданный сегмент в функцию и, наконец, извлекаем/используем значение из этого сегмента после вызова функции, который заполнит содержимое сегмента:
// char***
var suggestionsRef = allocator.allocate(ValueLayout.ADDRESS); // allocate space for an address
var suggestionCount = Hunspell_suggest(hunspellHandle, suggestionsRef, word);
// char** (the value set by the function)
MemoryAddress suggestions = suggestionsRef.get(ValueLayout.ADDRESS, 0);
После этого вы можете перебрать массив строк:
for (int i = 0; i < suggestionCount; i++) {
// char* (an element in the array)
MemoryAddress suggestion = suggestions.getAtIndex(ValueLayout.ADDRESS, i);
// read the string
String javaSuggestion = suggestion.getUtf8String(suggestion, 0);
}