Dart ffi - 使用 C

问题描述

我正在用 UTF-8 编码保存一个文件,其中包含一些信息,包括 Dart 端的按钮名称代码如下:

file.writeAsstring([
          name.length.toString(),name + Constants.nativeFileDelimeter,ids.length.toString(),ids.join(" "),].join(" "));

// Constants.nativeFileDelimeter is "|",it is used so that user can enter a name with whitespaces

我用 C 读取同一个文件,并使用 FFI 在 C 和 Dart 之间传递数据。

        FILE *file;

        file = fopen(filePath,"r");

        if (!file) {
            LOGE("Could not open %s!",filePath);
            *operationState = MediaLoadState::Failed_TO_LOAD;
            goto cleanup;
        }

        int32_t size;

        if(fscanf(file,"%d ",&size) != 1){
            LOGE("fscanf can not assign variables %s!",filePath);
            *operationState = MediaLoadState::Failed_TO_LOAD;
            goto cleanup;
        }

        // +1 because C strings ends with /0
        *namePtr = new char[size + 1];

        if (size != 0){
            if(fscanf(file,"%[^|]|",*namePtr) != 1){
                LOGE("fscanf can not assign variables %s!",filePath);
                *operationState = MediaLoadState::Failed_TO_LOAD;
                goto cleanup;
            }
        }

读取C保存的指针的Dart代码

  Pointer<Pointer<Utf8>> _namePtrPtr;
  String get name => Utf8.fromUtf8(_namePtrPtr.value);

我的问题是这段代码可以处理 0 个错误,它甚至可以处理日文、俄文字符,但是当引入表情符号时,事情变得很奇怪。当我保存包含表情符号的文件并尝试使用 C 和 Dart ffi 读取它时,我会收到 Utf8.fromUtf8 抛出的奇怪错误。例如:

Unfinished UTF-8 octet sequence (at offset 48)

有时它可以使用相同的代码来渲染表情符号,但后来应用程序会随机崩溃。每次读取文件时抛出的异常似乎都不同,有时我没有异常但后来崩溃了!它不一致。我不知道我做错了什么,我希望它可以与表情符号一起使用。谁能帮我解决这个问题?

解决方法

在 Dart 中,String.length 返回 UTF-16 代码单元的数量。要在 C 中读取 UTF-8,您需要知道 UTF-8 字节数。因此,在 Dart 代码中输出 utf8.encode(name).length 而不是 name.length(并导入 dart:convert)。异常和崩溃可能是由于尺寸过短引发的未定义行为。

以文本格式单独存储数据大小容易出错。最好使用这种方法:

您似乎在使用 C++。在那里,您可以将文件作为 std::ifstream 打开,创建一个 std::string name; 并使用 std::getline(file,name,'|'); 读取具有动态大小的名称。您可以使用 *namePtr = strdup(name.c_str())std::string 创建一个普通的 C 字符串。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...