?
Solved

global CArchive/CFile object

Posted on 1998-05-27
8
Medium Priority
?
352 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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

Percona Live Europe 2017 | Sep 25 - 27, 2017

The Percona Live Open Source Database Conference Europe 2017 is the premier event for the diverse and active European open source database community, as well as businesses that develop and use open source database software.

Question has a verified solution.

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

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…
Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
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.
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses
Course of the Month13 days, 15 hours left to enroll

801 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