openvino icon indicating copy to clipboard operation
openvino copied to clipboard

CacheManager: std::ofstream constructor error due to missing .c_str() call on std::wstring

Open max-my opened this issue 1 year ago • 9 comments

https://github.com/openvinotoolkit/openvino/blob/bdc01107d989310c6efa7dd61c7fa5743c971f1d/src/inference/src/cache_manager.hpp#L128

I encountered a compilation error while building the OpenVINO project, specifically in the cache_manager.hpp file. The error occurs when attempting to construct a std::ofstream object with a std::wstring argument without first calling .c_str().

Error Message:

src/inference/src/cache_manager.hpp:129:91: error: no matching function for call to ‘std::basic_ofstream<wchar_t>::basic_ofstream(std::wstring, std::_Ios_Openmode)’
  129 |         std::wofstream stream(getBlobFile(id), std::ios_base::binary | std::wofstream::out);

Proposed Fix:

To resolve the error, I suggest modifying the line to convert the std::wstring returned by getBlobFile(id) to a const char* using the .c_str() method before passing it to the std::ofstream constructor.

std::ofstream stream(getBlobFile(id).c_str(), std::ios_base::binary | std::ofstream::out);
...
auto blobFileName = getBlobFile(id).c_str();

Justification:

std::ofstream does not have an overload that accepts std::wstring directly. The .c_str() method is necessary to provide the correct type (const char*) expected by the constructor.

max-my avatar Sep 19 '24 09:09 max-my

Hi @max-my Could you please send this patch as PR to OpenVINO repo?

ilya-lavrenov avatar Sep 19 '24 09:09 ilya-lavrenov

The error you're encountering is due to the fact that std::ofstream does not support std::wstring directly. Instead, it expects a const char* or std::string. To fix this, you need to convert the std::wstring to a std::string or const char* before passing it to the std::ofstream constructor.Here’s how you can modify the code to resolve the compilation error:Convert std::wstring to std::string: This approach involves converting the std::wstring to std::string and then using the std::string with std::ofstream. Use std::wofstream for wide characters: If you need to handle wide characters, you should use std::wofstream instead of std::ofstream. Solution 1: Convert std::wstring to std::string #include #include

// Assuming getBlobFile(id) returns a std::wstring std::wstring getBlobFile(int id);

void someFunction(int id) { // Convert std::wstring to std::string std::wstring wstr = getBlobFile(id); std::string str(wstr.begin(), wstr.end());

// Use the converted std::string with std::ofstream
std::ofstream stream(str.c_str(), std::ios_base::binary | std::ofstream::out);
// ... rest of your code

}

Solution 2: Use std::wofstream for wide charactersIf you need to handle wide characters, you should use std::wofstream: #include #include

// Assuming getBlobFile(id) returns a std::wstring std::wstring getBlobFile(int id);

void someFunction(int id) { // Use std::wofstream for wide characters std::wofstream stream(getBlobFile(id), std::ios_base::binary | std::wofstream::out); // ... rest of your code }

Explanation:Choose the solution that best fits your needs. If you don't need to handle wide characters specifically, the first solution is generally more straightforward. If you do need to handle wide characters, the second solution is more appropriate.

KunjShah95 avatar Sep 19 '24 12:09 KunjShah95

maxmy kindly check it

KunjShah95 avatar Sep 19 '24 12:09 KunjShah95

kindlly check the above text which i made first it contains the solution if it helps u

KunjShah95 avatar Sep 19 '24 13:09 KunjShah95

The error you're encountering is due to the fact that std::ofstream does not support std::wstring directly. Instead, it expects a const char* or std::string. To fix this, you need to convert the std::wstring to a std::string or const char* before passing it to the std::ofstream constructor.Here’s how you can modify the code to resolve the compilation error:Convert std::wstring to std::string: This approach involves converting the std::wstring to std::string and then using the std::string with std::ofstream. Use std::wofstream for wide characters: If you need to handle wide characters, you should use std::wofstream instead of std::ofstream. Solution 1: Convert std::wstring to std::string #include #include

// Assuming getBlobFile(id) returns a std::wstring std::wstring getBlobFile(int id);

void someFunction(int id) { // Convert std::wstring to std::string std::wstring wstr = getBlobFile(id); std::string str(wstr.begin(), wstr.end());

// Use the converted std::string with std::ofstream
std::ofstream stream(str.c_str(), std::ios_base::binary | std::ofstream::out);
// ... rest of your code

}

Solution 2: Use std::wofstream for wide charactersIf you need to handle wide characters, you should use std::wofstream: #include #include

// Assuming getBlobFile(id) returns a std::wstring std::wstring getBlobFile(int id);

void someFunction(int id) { // Use std::wofstream for wide characters std::wofstream stream(getBlobFile(id), std::ios_base::binary | std::wofstream::out); // ... rest of your code }

Explanation:Choose the solution that best fits your needs. If you don't need to handle wide characters specifically, the first solution is generally more straightforward. If you do need to handle wide characters, the second solution is more appropriate.

Thank you for providing the two solutions. After careful review and testing, I've found that the first solution is well-suited for addressing the specific error we're encountering. While experimenting with the second solution, I encountered the need for additional code modifications due to the incompatibility of writer(stream); and reader(stream); with std::wofstream. The first solution, however, presents a more straightforward and efficient approach to achieving our desired outcome.

max-my avatar Sep 20 '24 01:09 max-my

Hi @max-my Could you please send this patch as PR to OpenVINO repo?

Yes, I'd be happy to contribute the patch to the OpenVINO repository. I'll prepare the PR with the necessary details and descriptions shortly. Thank you for the opportunity to contribute.

max-my avatar Sep 20 '24 01:09 max-my

I'm glad you liked the solution and that I could contribute to the project on GitHub; it was my first open source contribution.

KunjShah95 avatar Sep 20 '24 02:09 KunjShah95

DID IT FIX UR PROBLEM

KunjShah95 avatar Sep 28 '24 16:09 KunjShah95

I get a similar error in a different part of the code

openvino/src/core/src/pass/serialize.cpp:1266:77: error: no matching function for call to 'std::basic_ofstream<char>::basic_ofstream(const std::__cxx11::basic_string<wchar_t>&, std::_Ios_Openmode)'
 1266 |         std::ofstream bin_file(binPath_ref, std::ios::out | std::ios::binary);
      |                                                                             ^

This is using the very popular msys2/MINGW64. I have not updated it in a while; so. currently on gcc 14.1.0.

ddennedy avatar Oct 19 '24 20:10 ddennedy

Hello @max-my, have you created a PR? If not, let's reopen the task and allow someone else to do it. I'm reopening the task.

p-wysocki avatar Mar 05 '25 12:03 p-wysocki

.take

ahsmha avatar Mar 06 '25 18:03 ahsmha

Thanks for being interested in this issue. It looks like this ticket is already assigned to a contributor. Please communicate with the assigned contributor to confirm the status of the issue.

github-actions[bot] avatar Mar 06 '25 18:03 github-actions[bot]

@praasz I unassigned you because it forbids contributors from .taking the issue.

p-wysocki avatar Mar 24 '25 10:03 p-wysocki

.take

Recklore avatar Mar 30 '25 14:03 Recklore

Thank you for looking into this issue! Please let us know if you have any questions or require any help.

github-actions[bot] avatar Mar 30 '25 14:03 github-actions[bot]

The proposed solution/fix for of using the method ".c_str()" for converting the output of "getBlobFile()" form std::wstring to cons char* (but actually for std::wstring the "c_str()" returns const wchar_t*) will work fine for windows as it handles the const wchar_t* by itself, but on other systems like linux (which use UTF-8, they have only const char* filenames) this may cause some issues.

So the solution I am proposing is that create a variable of std::filesystem::path and store the return value of getBlobFile() into that and later use that variable to pass the path into the std::ofstream constructor as argument.

Recklore avatar Mar 30 '25 20:03 Recklore

i have launched a pull request for the issue which tries to use what i mentioned in the solution earlier but as I am new to github I am having issues with the PR check, i request for help regarding those.

Recklore avatar Apr 01 '25 05:04 Recklore