Solved

global CArchive/CFile object

Posted on 1998-05-27
8
346 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
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 

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

Problems using Powershell and Active Directory?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
sumDigits challenge 9 154
countEvens challenge 2 105
noX challenge 17 120
Problem to App source 6 41
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
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.
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…

832 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