M
Marc Cromme
I would like to ask a question about (good ?) style and possibilities in
mixing C FILE* and C++ file streams.
The background is that I want to use the C libpng library from within C++,
but I would like to open C++ file streams due to easier exception
handeling and safe closure of file ressources.
Question 1:
I open a standard file stream and want to transfer some binary read bits
to a function that accepts a pointer to unsigned char.
The solution I have found is:
std::ifstream pngInput(imgInfo.fileName().c_str(),
std::ios::in | std::ios::binary);
char sig[8];
pngInput.read(sig, 8);
png_check_sig(reinterpret_cast<unsigned char*>(sig), 8);
I consider this cast as a not-so-nice hack, which might fail on some other
platform. However, the obvious - opening a stream of unsigned chars - is
not that easy either, because there are no
char_traits<unsigned char>
defined on the system, that is,
std::basic_ifstream<unsigned char> pngInput(imgInfo.fileName().c_str(),
std::ios::in | std::ios::binary);
fails to compile. Question - is the hack really so bad as I feel, and is
it advisable to define some appropriate specialization of
char_traits<unsigned char> ??
....
Then comes some lines of code which might trow an exception ...
....
Question 2:
Further on I have to use a libpng function that expects a C-style file
pointer of type FILE* , but I have opened a C++ file stream, which I want
to feed it. The naive solution is of course not working, since there is no
conversion operator defined:
// compile time error, since function signature is
// int png_init(void*, FILE*)
png_init_io(png_ptr, pngInput );
// compile time error, no cast from std::ifstream will do
png_init_io(png_ptr, static_cast<FILE*>(pngInput) );
So the question is: is there a portable way to make a cast, or to acess
the underlying C-style file pointer FILE* from a std::ifstream???
If yes, how should this be done in a clean way, such that the file
ressource is properly released in case of exceptions?
I do thank you in advance for considering my C/C++ interfacing questions.
Sincierely, Marc Cromme, engineer
mixing C FILE* and C++ file streams.
The background is that I want to use the C libpng library from within C++,
but I would like to open C++ file streams due to easier exception
handeling and safe closure of file ressources.
Question 1:
I open a standard file stream and want to transfer some binary read bits
to a function that accepts a pointer to unsigned char.
The solution I have found is:
std::ifstream pngInput(imgInfo.fileName().c_str(),
std::ios::in | std::ios::binary);
char sig[8];
pngInput.read(sig, 8);
png_check_sig(reinterpret_cast<unsigned char*>(sig), 8);
I consider this cast as a not-so-nice hack, which might fail on some other
platform. However, the obvious - opening a stream of unsigned chars - is
not that easy either, because there are no
char_traits<unsigned char>
defined on the system, that is,
std::basic_ifstream<unsigned char> pngInput(imgInfo.fileName().c_str(),
std::ios::in | std::ios::binary);
fails to compile. Question - is the hack really so bad as I feel, and is
it advisable to define some appropriate specialization of
char_traits<unsigned char> ??
....
Then comes some lines of code which might trow an exception ...
....
Question 2:
Further on I have to use a libpng function that expects a C-style file
pointer of type FILE* , but I have opened a C++ file stream, which I want
to feed it. The naive solution is of course not working, since there is no
conversion operator defined:
// compile time error, since function signature is
// int png_init(void*, FILE*)
png_init_io(png_ptr, pngInput );
// compile time error, no cast from std::ifstream will do
png_init_io(png_ptr, static_cast<FILE*>(pngInput) );
So the question is: is there a portable way to make a cast, or to acess
the underlying C-style file pointer FILE* from a std::ifstream???
If yes, how should this be done in a clean way, such that the file
ressource is properly released in case of exceptions?
I do thank you in advance for considering my C/C++ interfacing questions.
Sincierely, Marc Cromme, engineer