473,394 Members | 1,806 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

mixing C FILE* and C++ file streams ??


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
Jul 22 '05 #1
1 3381
A few things,

1. In your context (reading an image into a buffer), casting char to
unsigned char should not be a big deal. I mean, you are reading the
data into an array of char, which is a limitation by the read function.
In reality you are just reading into an array of data which its
sizeof is 1. Therefore, you are trying to read the data into an array
of bytes, whitout reagards to the interpretation. In your case, libpng
is telling you that the data should be an unsigned char, therefore the
need for the cast. You can't escape this, and it is bening in this
case, as sizeof(char) == sizeof(unsigned char), unlike shorts or ints
that would require you to consider endianism...

2. Unless you know exactly what you are doing, defining traits for
types might be very dangerous. If you get it to work, do it,, just be
careful...

3. You are using C++ streams and mixing it with read. This is usually
not a great idea. In this scenario, I fail to see the advantage to using
FILE*, or just file descriptors. I mean, You can always use errno to
give you errors, and basic_stream.read is not any better than ::read (in
my opinion, at least)

I personally would do...
try{
std::string filename = "file.ext";
std::string mode = "r";

struct stat st;
if(stat(filename.c_str(), &st) == -1)
{
throw MyException( std::string("Could not stat file due to: ") +
strerror(errno));
}

FILE* f = fopen(filename.c_str(), mode.c_str());
if(NULL == f)
{
throw MyException( std::string("Error opening file due to: ") +
strerror(errno));
}

int fileSize = st.st_size;
char* buf = new char[fileSize];

int bytesRead = ::fread(f, buf, sizeof(char), fileSize);

if(bytesRead < st.st_size)
{
delete[] buf;
fclose(f);
throw MyException( std::string("Error readingfile due to: ") +
strerror(errno));
}

... Do whatever....
delete[] buf;
fclose(f);

}
catch(MyException& me)
{
}
catch(std::exception& stde)
{
}
catch(...)
{
}

Of course, you can see that this could well be encapsulated in a simple
C++ object, one in which you could make sure that the resources are
properly handled....
Marc Cromme wrote:
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

Jul 22 '05 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: sb | last post by:
I think streams are nice, but what do you do when you have to write to or, even worse, read from a FILE*, for example a UNIX stream? C++ streams can not be created from FILE*'s or have them...
3
by: Tron Thomas | last post by:
What does binary mode for an ofstream object do anyway? Despite which mode the stream uses, operator << writes numeric value as their ASCII representation. I read on the Internet that it is...
6
by: radnoraj | last post by:
Hi, I am sucessfull in redirecting console output to a file. but in this case nothing is displayed on the console, cout output is written to file without display. how do write the output to...
3
by: Tim | last post by:
Hi I have a program that I had written in Managed C++ that writes messages to the console while running. I wanted to allow the user to enter commands at the console as well, but this became...
1
by: Andy | last post by:
Can I mix wide and narrow character output to stdout? I seem to remember hearing this was not supported before but I can't find any reference to such a restriction now I actually need to do it! It...
9
by: Salman | last post by:
How to mix C and C++ ?
1
AdrianH
by: AdrianH | last post by:
Assumptions I am assuming that you know or are capable of looking up the functions I am to describe here and have some remedial understanding of C programming. FYI Although I have called this...
2
by: Ralf Goertz | last post by:
Hi, can I mix output to cout and wcout? It seems that if I write to cout first it works fine but if I start with wcout the output to cout vanishes. I assume that is has to do with the...
2
by: =?Utf-8?B?QXJ0?= | last post by:
I need to go through a folder and all of its subfolders and collect the Title, Comments, Keywords and a few other items. These are items that you see when you select a file in the Windows explorer...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.