如何在Webassembly中构建和使用libicu

时间:2018-12-21 06:53:34

标签: icu webassembly

我对一个JavaScript项目(在浏览器中)的ICU63库的单词迭代器感兴趣。因此,阅读文档后,我相信ICU默认使用UTF-16,它与JS相同,并且可以避免我将JS字符串编码为其他内容。

第一步是用我需要的唯一功能构建包装器(我不知道它是否在起作用):

#include "emscripten.h"
#include <string.h>
#include <unicode/brkiter.h>
#include <unicode/unistr.h>
#include <unicode/errorcode.h>

using namespace icu_63; 

EMSCRIPTEN_KEEPALIVE
int splitWords(const char *locale, const uint16_t *text, uint16_t *splitted) {
    //Note that Javascript is working in UTF-16
    //icu::
    UnicodeString result = UnicodeString();
    UnicodeString visibleSpace = UnicodeString(" ");
    int32_t previousIdx = 0;
    int32_t idx = -1;

    //Create a Unicode String from input
    UnicodeString uTextArg = UnicodeString(text);
    if (uTextArg.isBogus()) {
        return -1; // input string is bogus
    }

    //Create and init the iterator
    UErrorCode err = U_ZERO_ERROR;
    BreakIterator *iter = BreakIterator::createWordInstance(locale, err);
    if (U_FAILURE(err)) {
        return -2; // cannot build iterator
    }
    iter->setText(uTextArg);

    //Iterate and store results
    while ((idx = iter->next()) != -1) {
        UnicodeString word = UnicodeString(uTextArg, idx, idx - previousIdx);
        result += word;
        result += visibleSpace;
        previousIdx = idx;
    }
    result.trim();
    //The buffer contains UTF-16 characters, so it takes 2 bytes per point
    memcpy(splitted, result.getBuffer(), result.getCapacity() * 2);
    return 0;
}

它编译并且看起来不错,但是在尝试链接时会丢失符号,因为我不知道如何进行操作。

LibICU看起来需要大量的内置数据。就我而言,频率表对于使用单词迭代器是必不可少的。

我应该尝试将包装程序复制到源文件夹中,并尝试弄清楚如何使用 emconfigure 。还是在我尝试编译包装程序时链接libicu?第二种选择似乎浪费了数据,因为我对lib的大部分内容不感兴趣。

1 个答案:

答案 0 :(得分:2)

以我的经验,处理库的最简单方法是先使用emconfigure / emmake构建库,然后将其与您自己的代码静态链接。如下所示:

$ emcc your_wrapper.cpp \
       your_compiled_libICU_static_lib.a \
       -o result.js

有时使用emconfigure / emmake编译库非常困难,因为您可能需要修改源代码才能使其在WebAssembly中运行。

但是... 好消息! Emscripten提供了一些流行且复杂的库and ICU is one of them的端口。

您可以使用-s USE_ICU=1标志来编译代码,而无需自己编译ICU:

$ emcc your_wrapper.cpp \
       -s USE_ICU=1 \
       -s ERROR_ON_UNDEFINED_SYMBOLS=0 \
       -std=c++11

需要注意的是Emscripten ICU端口是ICU62。因此,您需要将using namespace icu_63;更改为using namespace icu_62;