7

我正在试验Hunspell以及如何使用Java Project Panama(Build 19-panama+1-13 (2022/1/18))与之交互。我能够完成一些初始测试,例如创建 ahandle to Hunspell并随后使用它来执行拼写检查。我现在正在尝试更详细的方法,让 Hunspell 给我suggestions一个字典中没有的单词。这是我现在拥有的代码:

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);
            }
        }
    }
}

我所看到的是对Hunspell_suggest(created from jextract) 的调用成功并给了我 (4) 建议(我在命令行中使用 Hunspell 进行了验证) - 所以那里没有问题。

现在对我来说更具挑战性的是如何解开suggestions从这个调用返回的元素?我一直在查看各种示例,但似乎没有一个涉及这种详细程度(即使我找到示例,它们似乎使用的是过时的巴拿马 API)。

所以本质上,这是我的问题:

我如何使用巴拿马 JDK19 API 将一个据称由指向字符串数组的指针组成的结构解压缩到它们各自的字符串集合?

4

1 回答 1

3

在这里查看标题: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);

slst是一个经典的“out”参数。即我们传递一个指向某个值的指针(在这种情况下是char**一个字符串数组),函数将为我们设置这个指针,作为返回多个结果的一种方式。(第一个结果是建议的数量)

在巴拿马,您通过分配具有参数是指针的类型的布局的段来使用“输出”参数。在这种情况下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);
}
于 2022-02-24T21:19:16.273 回答