проблема преобразования wstring c ++ в c # для пути к файлу Unicode с Swig - PullRequest
0 голосов
/ 18 октября 2019

Я работаю над преобразованием библиотек c ++ (CNTK) в c # с помощью swig в Ubuntu 18.04. После успешного преобразования я попытался вызвать функцию со строкой (путь к файлу), я высеял эту ошибку.

Во-первых,

System.ApplicationException: Cannot open file 'ResNet_18.model' for reading.

[CALL STACK]
[0x7f80a702a4]                                                         + 0x7012a4
[0x7f80bed898]      CNTK::  GetFstream  (std::__cxx11::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>> const&,  bool) + 0x200
[0x7f80a75dc4]      CNTK::Function::  Load  (std::__cxx11::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>> const&,  CNTK::DeviceDescriptor const&,  CNTK::ModelFormat) + 0x7c
[0x7f80a765dc]      CNTK::Function::  Load  (std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>> const&,  CNTK::DeviceDescriptor const&,  CNTK::ModelFormat) + 0x1ac
[0x7f81638338]      CSharp_CNTK_Function__Load__SWIG_0                 + 0x180
[0x7f783b4a40]

  at CNTK.Function._Load (System.String filepath, CNTK.DeviceDescriptor computeDevice, CNTK.ModelFormat format) [0x00031] in <b00f46cf6d58434dafaf33b4c3dc697b>:0
  at CNTK.Function.Load (System.String filepath, CNTK.DeviceDescriptor computeDevice, CNTK.ModelFormat format) [0x00000] in <b00f46cf6d58434dafaf33b4c3dc697b>:0
  at cntk_test.MainClass.Main (System.String[] args) [0x00012] in /home/aiware/Projects/cntk_test/cntk_test/Program.cs:17

и эта ошибка также.

System.ExecutionEngineException: String conversion error: Illegal byte sequence encounted in the input.
  at at (wrapper managed-to-native) System.Object.__icall_wrapper_ves_icall_string_new_wrapper(intptr)
  at at (wrapper native-to-managed) CNTK.CNTKLibPINVOKE+SWIGExceptionHelper.SetPendingApplicationException(intptr)
  at at (wrapper managed-to-native) CNTK.CNTKLibPINVOKE.Function__Load__SWIG_0(string,System.Runtime.InteropServices.HandleRef,int)
  at CNTK.Function._Load (System.String filepath, CNTK.DeviceDescriptor computeDevice, CNTK.ModelFormat format) [0x00001] in /home/aiware/Projects/cntk_test/cntk_test/Function.cs:293
  at CNTK.Function.Load (System.String filepath, CNTK.DeviceDescriptor computeDevice, CNTK.ModelFormat format) [0x00001] in /home/aiware/Projects/cntk_test/cntk_test/FunctionShim.cs:267
  at cntk_test.MainClass.Main (System.String[] args) [0x00012] in /home/aiware/Projects/cntk_test/cntk_test/Program.cs:17

И я посмотрел на код c ++, эта функция вызывается с помощью wstring. Я предполагаю, что у c # нет wstring, поэтому свинг конвертирует wstring в строку. Так как я переопределяю функцию в c ++, чтобы преобразовать строку в wstring и перестроить их. Но он все еще имеет ту же ошибку.

оригинальный код, который я хочу использовать

/*static*/ FunctionPtr Function::Load(const std::wstring& filepath, const DeviceDescriptor& computeDevice, ModelFormat format)
{
     switch (format)
     {
     case ModelFormat::CNTKv2:
     {
         auto stream = GetFstream(filepath, true);
         if (!Internal::IsLegacyModel(*stream))
         {
             Dictionary model;
             *stream >> model;
             return Function::Deserialize(model, computeDevice);
         }
         else
         {
             return Internal::LoadLegacyModel(filepath, computeDevice); // throw an exception if deserializer != nullptr?
         }
         break;
     }
     case ModelFormat::ONNX:
         return ONNXFormat::Load(filepath, computeDevice);
         break;
     }

     return nullptr;
}

эти строки я пытался добавить

/* Source/CNTKv2LibraryDll/API/CNTKLibrary.h */
/// Load a Function from a model file
CNTK_API static FunctionPtr Load(const std::string& filepath, 
          const DeviceDescriptor& computeDevice = DeviceDescriptor::UseDefaultDevice(),
          ModelFormat format = ModelFormat::CNTKv2);

/* Source/CNTKv2LibraryDll/Function.cpp */
/*static*/ FunctionPtr Function::Load(const std::string& filepath, const DeviceDescriptor& computeDevice, ModelFormat format)
{
  std::wstring wfilepath;
  wfilepath.assign(filepath.begin(),filepath.end());
  return Load( wfilepath, computeDevice, format );
}
...