无法将非 ASCII 文件名从 NodeJS 传递到 C++ 模块

问题描述 投票:0回答:1

我想将文件路径信息从 NodeJS 发送到我自己的模块(使用 node-addon-api 的 C++)。每一方独立工作(即我可以在 NodeJS 和 C++ 中检查/打开文件)。但是,如果要将包含 ä、ö、ü 等字符的路径变量从 NodeJS 发送到 C++,则会失败。

这是检查路径是否存在、将路径和结果写入文件并返回该结果的代码:

// PathJSON.h
#pragma once
#include <filesystem>
#include <format>
#include <fstream>
#include <string>

namespace test_json {
  std::string checkPathInJSON(const char* json) {
    std::string pathString = json;
    std::filesystem::path p(pathString);
    std::string outString = "";
    if (std::filesystem::exists(p)) {
      outString = std::format("{};exists", pathString);
    }
    else {
      outString = std::format("{};MISSING", pathString);
    }
    std::filesystem::path logPath("d:/filelog.csv");
    std::ofstream ofs(logPath, std::ios::app);
    if (ofs.is_open()) {
      ofs << outString << std::endl;
      ofs.close();
    }
    return outString;
  }
}
// Central.cpp
#include <iostream>
#include "PathJSON.h"

int main() {
  std::string str = test_json::checkPathInJSON("D:/foo.txt");
  std::cout << str << std::endl;  // D:/foo.txt;exists
  str = test_json::checkPathInJSON("D:/föö.txt");
  std::cout << str << std::endl;  // D:/föö.txt;exists
}

在 C++ 项目中测试此代码可以为控制台和文件提供预期结果:

// filelog.csv
D:/foo.txt;exists  // correct
D:/föö.txt;exists  // correct

这里是相应的

NodeJS
模块(改编自官方“hello world”示例):

// hello.cc
#include <iostream>
#include <napi.h>
#include "PathJSON.h"

Napi::String Method(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  std::string str = "";
  if(info.Length() == 1 && info[0].IsString()) {
    std::string par = info[0].As<Napi::String>();
    std::cout << par << std::endl;
    str = test_json::checkPathInJSON(par.c_str());
  }
  return Napi::String::New(env, str);
}

Napi::Object Init(Napi::Env env, Napi::Object exports) {
  exports.Set(Napi::String::New(env, "hello"), Napi::Function::New(env, Method));
  return exports;
}

NODE_API_MODULE(node_api_1, Init);

调用模块:

// hello.js
console.log(addon.hello("D:/foo.txt"));
console.log(addon.hello("D:/föö.txt"));

这会产生以下输出:

// filelog.csv
D:/foo.txt;exists   // correct
D:/föö.txt;MISSING  // ERROR

如您所见,模块报告包含特殊字符(“Umlaute”)的文件不存在 - 然而,它正在将正确的文件名写入日志文件,我不知道问题出在哪里!

那么,我该如何解决这个问题,以便我可以打开包含非 ASCII 字符的文件?

提前感谢您的帮助!

P.S.:我也尝试过使用

rapidjson
来传递数据(实际上,这是我通常用来传递所有信息的)。另外,我尝试了路径的不同变体,例如
D:\\föö.txt
D:\\\\föö.txt
等等..

c++ node.js path node-modules
1个回答
0
投票

Napi::String
转换为
std::string
会得到一个 UTF-8 编码的字符串,Windows 文件 API 不支持 UTF-8。

如果您转换为

std::u16string
那么
std::filesystem
应该按预期工作:

std::u16string par = info[0].As<Napi::String>();
std::filesystem::path p(par)
© www.soinside.com 2019 - 2024. All rights reserved.