Re: CFile and FILE*
- From: "Ian Semmel" <anyone@xxxxxxxxxxxxxxxxx>
- Date: Thu, 27 Mar 2008 05:49:40 +0000
Thanks for your comments. I didn't intend to leave the code as it is, but this is what MS provided !
Investigating further, I see how the CStdio solution is better. As I said, I don't want to touch the function I'm calling (which is not what is in the example) so as long as I get the FILE* I'm OK.
"Joseph M. Newcomer" <newcomer@xxxxxxxxxxxx> wrote in message news:ecrlu315flk9bcu64tlqlngpk1e6boqqpn@xxxxxxx:
See below...
On Wed, 26 Mar 2008 21:14:54 +0000, "Ian Semmel"
<anyone@xxxxxxxxxxxxxxxxx> wrote:
>Thanks,
>
>Using that link, this modification seems to work (although needs
>development)
>*********************************************************
>#include "StdAfx.h"
>#include <stdlib.h>
>#include <stdio.h>
>#include <fcntl.h>
>#include <io.h>
>#include "CrtFile.h"
>
>FILE* CrtFile ( CFile* pCFile )
>{
> HFILE OsFileHandle;
> FILE *stream;
> int CrtFileHandle;
>
> OsFileHandle = (HFILE) (pCFile ->m_hFile); // I added this ???
****
Note that before using the stream for any purpose, that you have flushed
alll the pending
I/O on it. The low-level I/O does no buffering, but if there is
buffered data, you are
going to be in trouble.
Why not use a CStdioFile and return the m_pStream handle? Then you have
no such problem.
*****
>
> /* convert OS file handle to CRT file pointer */
> if ( (CrtFileHandle=_open_osfhandle(OsFileHandle,_O_RDONLY))==-1){
> printf( "_open_osfhandle Failed");
> exit(1);
****
This would be a Really Bad Idea. Never, ever call exit() in any C++
program, in any
Windows program, or, now that I stop to think of it, in any program,
ever, for any reason.
Existing files will not be properly closed, for example, in any kind of
program, including
console apps. There are too many things that can go wrong. I had made
it a policy to
NEVER call exit() by 1980 or so (I was still faculty at CMU at the time,
and I left in
early 1981). It is a lazy hack that avoids writing reliable and robust
code.
****
> }
>
> /* Change handle access to stream access. */
> if( (stream = _fdopen( CrtFileHandle, "r" )) == NULL ) {
****
embedding assignment statements in if-statements is poor style. Avoid
doing this
****
> printf( "_fdopen Failed");
> exit( 1 );
****
See previous comment on exit()
****
> }
>
> return stream;
>}
>
>void TestFile ()
>{
> CFile* pCFile = new CFile ( "test.txt", CFile::modeRead );
>
> FILE* stream = CrtFile ( pCFile );
>
> char inbuf[128];
> int count = 0;
>
> while( fgets( inbuf, 128, stream ) != NULL )
> count++;
>
> CString str;
> str.Format ( "Lines=%d", count );
> AfxMessageBox ( str );
>}
>*********************************************************
>I needed this because I am writing data to an ancient device (firmware
>unchangeable) which requires me to use the old compression algorithm
>compress.c (which was written some time in the 1980's). As this code
>uses every bad construct of the "C" language, I am loathe to try to
>change it to C++.
****
If you have the source for it, redirecting what it sends to someplace
useful is not the
same as rewriting it. You can even use a CALLBACK function with a
length and a generic
LPVOID, e.g.,
void DoSomething(FILE * f, other_parameters)
{
....
fwrite(buffer, size, count, f);
could easily be replaced by
void DoSomething(
BOOL (CALLBACK* func)(LPVOID buffer, DWORD len,
LPVOID user),
LPVOID user, other_parameters)
{
...
if(!func(buffer, size * count, user))
...deal with FALSE return, for example
}
which would strike me as considerably lower-risk that playing games with
low-level file
handles and similar tricks. Note that you can still compile this as C
code and the syntax
given can still work, but if you don't want to use any header files like
windows.h, you
could write it as
int (__stdcall * func)(void * buffer, unsigned long len, void *
user),
void * user, other_parameters)
which will compile under the C compiler without incident.
joe
****
>
>
>"Victor" <nijegorodov.otpusk@xxxxxxxxxx> wrote in message
>news:#BoQApsjIHA.4076@xxxxxxxxxxxxxxxxxxxx:
>
>> Have a look at _open_osfhandle function and KB139640 ("Do Not Mix
>> Operating
>> System and CRT File Handles") in MSDN:
>> http://support.microsoft.com/kb/139640
>>
>> Victor
>>
>> "Ian Semmel" <anyone@xxxxxxxxxxxxxxxxx> wrote in message
>> news:OtWxvmqjIHA.3512@xxxxxxxxxxxxxxxxxxxxxxx
>>
>> > Is there any way to call a function expecting a FILE* using an
opened
>> > CFile ?
>> >
>> >
Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.
- References:
- Re: CFile and FILE*
- From: Joseph M . Newcomer
- Re: CFile and FILE*
- Prev by Date: Re: Saving an XML file from VC++ application
- Next by Date: Re: Cylinder Drawing Essay
- Previous by thread: Re: CFile and FILE*
- Next by thread: Re: CFile and FILE*
- Index(es):
Relevant Pages
|