Reputation: 13
I've looked up on Internet to see if someone encountered that problem, but haven't found anything.
So I'm trying to use a C++ DLL in a C# UWP application. This DLL has a log file which is opened at the beginning of the code with the following function:
#include <string>
#include <iostream>
using namespace std;
int Logger::set(string file_name, bool clear_log) {
_file_stream.exceptions(ofstream::failbit | ofstream::badbit);
try {
_file_stream.open(file_name, ios_base::out | (clear_log ? ios_base::trunc : ios_base::app));
}
catch (ofstream::failure) {
return -1;
}
_file_stream << "";
return 0;
}
Here is the code of the Logger class:
class Logger {
private:
std::ofstream _file_stream;
public:
Logger() {};
~Logger() { _file_stream.close(); };
int set(std::string file_name, bool clear_log);
}
Now, this code works fine when I use the DLL in standalone mode. But when called via the UWP app, the open() function throws an ofstream::failure exception saying:
ios_base::failbit set: iostream stream error
I first thought this was due to UWP's weird access rights policies, but after debugging, file_name
points to the correct package folder in AppData, so it should be okay to write a file here.
What could be the problem?
EDIT: I found out that for some reason, the C file API works as expected. That is, the following code successfully creates the file:
#include <iostream>
using namespace std;
int Logger::set(string file_name, bool clear_log) {
FILE* test = fopen(file_name.c_str(), clear_log ? "w" : "a");
if(!test)
{
return -1;
}
fprintf(test, "");
return 0;
}
Upvotes: 0
Views: 149
Reputation: 13
I figured out myself after some more active debugging. Somewhere before in the code this similar (indirect) call to ofstream::open didn't fail:
ofstream out("out.txt", ios_base::trunc);
And by putting breakpoints on the right place, I was able to determine that in that case, the value of the open mode (the ios_base::trunc
argument) resolved to 18 (the expected value), whereas it resolved to the weird value 1594 in the problematic case, when using the ternary operator.
Replacing the ternary operator by a if-else block resolved the problem:
int Logger::set(string file_name, bool clean_log) {
_file_stream.exceptions(ofstream::failbit | ofstream::badbit);
try
{
if (clean_log)
_file_stream.open(file_name, ios_base::trunc);
else
_file_stream.open(file_name, ios_base::app);
}
catch (ofstream::failure)
{
return -1;
}
return 0;
}
Upvotes: 0