Solved

global CArchive/CFile object

Posted on 1998-05-27
8
345 Views
Last Modified: 2013-11-20
i need a pair of CFile/CArchive objects that are accessible to all classes in the program in order to log possible errors occured during processing data. any suggestions?
is there a better way around this than declare CFile/CArchive objects as external?
0
Comment
Question by:flexsuite
  • 4
  • 2
  • 2
8 Comments
 
LVL 3

Expert Comment

by:tma050898
ID: 1315599
You could place them both in the applicatoin object. That way you can easily access them from anywere in the application via the AfxGetApp function (after casting the returned CWinApp pointer). Lemme know if you need more detail.
0
 

Author Comment

by:flexsuite
ID: 1315600
i am developing a win32 dll which does not have a CWinApp object. what shall i do?
0
 
LVL 3

Expert Comment

by:tma050898
ID: 1315601
Ok. The file objects both live in a DLL. Why couldn't the DLL simply export two functions to retrieve pointers or references to the file objects?
0
 

Author Comment

by:flexsuite
ID: 1315602
the file is processed inside the dll using buffered output method. the information to be placed in the file is gathered from various objects of different classes and stored in the archive. once the job is finished, the information stored in archive will be serialized into the file object. suggestions?
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 3

Expert Comment

by:tma050898
ID: 1315603
I guess I'm just not seeing anything too problematic here. What am I missing?

You have a couple of file objects in the DLL. Both of these objects get written to by various objects in the appliction. The application's object accomplishs this by calling exported functions from the DLL. Conversely, the DLL could also wrap this functionality in a C++ class and export the entire class or a set of its member functions for the application's objects to call.

Tom

0
 
LVL 4

Accepted Solution

by:
piano_boxer earned 100 total points
ID: 1315604
Maby this is what you want.

In my app I log internal status/error messages to a textfile. The nice thing about my approach is that you can add log-messages just like calling printf().

-

Create a new cpp/h file pair called log.cpp and log.h and insert the code.

*** USAGE:

Call OpenLogFile(_T("mylog.txt")) in your CWinApp::OnInitInstance().
Call CloseLogFile() in your CWinApp::ExitInstance().

Include the 'log.h' file in every .cpp file that you want to call
WriteLog from, or just include globally in stdafx.h

Here is some example of writing to the logfile:


1.  WriteLog(_T("Application started"));
2.  WriteLog(_T("Error writing %d bytes to socket"), nByteCount);
3.  WriteLog(_T("Cannot find the file: %s"), strFile);



------------- START OF LOG.H -------------------

#ifdef __LOG_H__
#define __LOG_H__

BOOL OpenLogFile(LPCTSTR lpszFilename);
void CloseLogFile()
void WriteLog(LPCTSTR lpszFmt, ...)

#define MAX_LOGFILE_SIZE 1024 * 1024; // 1MB

#endif



------------- START OF LOG.CPP -----------------

#include "stdafx.h"
#include "log.h"

HANDLE g_hLogFile = NULL;


BOOL OpenLogFile(LPCTSTR lpszFilename)
{
    ASSERT(lpszFilename != NULL);
    ASSERT(g_hLogFile == NULL);

    // Open existing or create new logfile and
    // move to end of file.
    g_hLogFile = CreateFile(
        lpszFilename,
        GENERIC_READ|GENERIC_WRITE,
        FILE_SHARE_READ,
        NULL,
        OPEN_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL );
    if(g_hLogFile == INVALID_HANDLE_VALUE)
    {
        g_hLogFile = NULL;
        return FALSE;
    }

    SetFilePointer(g_hLogFile, 0, 0, FILE_END);

    // Add a new-line to the text-file
    DWORD dw;
    WriteFile(g_hLogFile, _T("\r\n"), 2, &dw, NULL);

    return TRUE;
}

void CloseLogFile()
{
    if(g_hLogFile != NULL)
    {
        CloseHandle(g_hLogFile);
        g_hLogFile = NULL;
    }
}


////////////////////////////////////////////////////////
// The following function is used to adjust the size of
// the logfile so that it does not exceed a gived size
//
// The oldest entries are deleted first.
//
void AdjustLogFileSize()
{
    if(g_hLogFile == NULL)
    {
        ASSERT(FALSE);
        return;
    }

    //
    // Get current size of file and determine if we need to adjust the size.
    // If the logfile is greater that dwMax then the size if adjusted to:
    // Filesize - MAX_LOGFILE_SIZE/10
    //
    DWORD dwIoSize;
    DWORD dwSize = GetFileSize(g_hLogFile, NULL);
    if(dwSize > (MAX_LOGFILE_SIZE/10))
        dwSize -= (MAX_LOGFILE_SIZE/10);

    if(dwSize > MAX_LOGFILE_SIZE)
    {
        // Move to the position in the file where we want to cut, and scan forward to the
        // first newline. This way we do not cut any lines i half.
        DWORD dwSrcPos = dwSize - MAX_LOGFILE_SIZE;
        VERIFY(SetFilePointer(g_hLogFile, dwSrcPos, NULL, FILE_BEGIN) !=  0xFFFFFFFF);
        char c = 0;
        while(c != '\n' && dwSrcPos < dwSize)
        {
            if(!ReadFile(g_hLogFile, &c, 1, &dwIoSize, NULL))
                break;

            dwSrcPos++;
        }

        // Move data from ending to the beginning of file and set new EOF
        // We move 10KB at a time.
        DWORD dwReduce = dwSize - dwSrcPos;

        DWORD dwDstPos = 0;
        BYTE buf[10240];
        while(dwSrcPos < dwSize)
        {
            SetFilePointer(g_hLogFile, dwSrcPos, NULL, FILE_BEGIN);
            dwIoSize = 0;
            if(!ReadFile(g_hLogFile, buf, sizeof(buf), &dwIoSize, NULL) || !dwIoSize)
                break;

            SetFilePointer(g_hLogFile, dwDstPos, NULL, FILE_BEGIN);
            if(!WriteFile(g_hLogFile, buf, dwIoSize, &dwIoSize, NULL))
                break;

            dwSrcPos += dwIoSize;
            dwDstPos += dwIoSize;
        }

        // Set new EOF
        SetEndOfFile(g_hLogFile);
    }
}


////////////////////////////////////////////////////////
// This function will write to the logfile. Just call it
// as a normal printf() call.
//
// Every entry is timestamped.

void WriteLog(LPCTSTR lpszFmt, ...)
{
    if(g_hLogFile == NULL)
    {
        ASSERT(FALSE);
        return;
    }

    // Format the string based on lpszFmt and corresponding
    // parameters (if any).

    va_list argList;
    va_start(argList, lpszFmt);

    char sz[1024];

    CString s1;
    CTime tm;
    DWORD dwIoSize;

    tm = CTime::GetCurrentTime();

    _vstprintf(sz, lpszFmt, argList);

    va_end(argList);

    s1 = tm.Format(_T("%c"));
    s1 += _T(" ");
    s1 += sz;
    s1 += _T("\r\n");

    // Write to logfile and adjust size if neccessary.
    WriteFile(g_hLogFile, (LPCSTR)s1, s1.GetLength(), &dwIoSize, NULL);
    AdjustLogFileSize();
};
0
 
LVL 4

Expert Comment

by:piano_boxer
ID: 1315605
I just spotted one mistake in my code:
  #ifdef __LOG_H__
should be replaced with
  #ifndef __LOG_H__

0
 
LVL 3

Expert Comment

by:tma050898
ID: 1315606
flexsuite,

I'm glad that you finally got an answer to your question. However, one piece of advice. If you take a little more time to word your questions, next time you will get a much quicker resolution to your problem.

Your question stated...
"is there a better way around this than declare CFile/CArchive objects as external?"

This lead me to believe that your problem had nothing to do with how to log error messages. After reading your question, I thought that you already had that code written. In fact, from the question it looked like the only problem you had dealt with not knowing how make that logging capability available to the DLL's client code which is why I wasted both of our time with answers that in now way dealt with your problem.

Tom

0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now