Solved

global CArchive/CFile object

Posted on 1998-05-27
8
347 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
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 

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
 
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

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Login Script to Copy Folders 12 42
mapBully challenge 6 152
Detect file exist or not 3 178
Is there a simple front-end menu system. 9 102
This is to be the first in a series of articles demonstrating the development of a complete windows based application using the MFC classes.  I’ll try to keep each article focused on one (or a couple) of the tasks that one may meet.   Introductio…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
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.
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…

809 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