注:mfclog.dll 中定义了类 LogFilevoid CMy111Dlg::OnButton2() 
{
// TODO: Add your control notification handler code here
typedef void (*lpFun)(void);
HINSTANCE hDll; //DLL句柄 hDll = LoadLibrary("E:\\VC_XueXi\\MyHis\\LogUpdate\\mfcLog\\Debug\\mfclog.dll");if (NULL==hDll){MessageBox("DLL加载失败");}

lpFun addFun; //函数指针lpFun pShowDlg = (lpFun)GetProcAddress(hDll,"LogFile");//pShowDlg log;if (NULL==pShowDlg){MessageBox("DLL中类寻找失败"); }
else MessageBox("DLL中类寻找成功!!!"); }

解决方案 »

  1.   

    要做成扩展DLL,才能使用类。
      

  2.   

    我从网上下载了一个日志类,全部写在Log.cpp中。我想写一个win32 DLL, 并将代码分开,(log1.cpp 和 log1.h)下面是源代码Log.cpp
    /*
    Log File Library(WIN98/NT/2000) Compile by: BC++ 5; C++ BUILDER; VC++; VC.NET; copyright(c) 2004.5 - 2005.3  llbird [email protected] http://blog.csdn.net/wujian53*/
    /*
    Use:
    //这个代码我用工业现场24X7值守的程序纪录各种信息, 简单易用;
    //一般用一个全局日志对象, 有临界排斥可以多线程安全使用。
    //有两个类
    class LogFile;//用户定义日志文件名
    class LogFileEx;//有日志文件名自动生成功能 , 可分年月日频率生成文件名, 可指定日志存放的目录LogFile gLog("My.Log");
    gLog.Log("test", 4);//记录日志
    gLog.Log("系统启动");LogFileEx gLog(".", LogFileEx :: YEAR);//一年生成一个日志文件
    LogFileEx gLog(".\\Log", LogFileEx :: MONTH);//一月生成一个日志文件
    LogFileEx gLog(".\\Log", LogFileEx :: DAY);//一天生成一个日志文件
    //注意日志所属目录创建失败会自动退出, 请注意目录的合法性, 文件生成频率看情况掌握
    //24小时运行的程序可以每天生成一个日志文件, 以免内容过多
    */#ifndef _LOGFILE_H
    #define _LOGFILE_H
    #endif
    #include <ASSERT.h>
    #include <time.h>
    #include <stdio.h>
    #include <windows.h>
    #include "stdafx.h"class LogFile
    {
    protected: CRITICAL_SECTION _csLock;
     char * _szFileName;
     HANDLE _hFile; bool OpenFile()//打开文件, 指针到文件尾
     {
      if(IsOpen())
       return true;  if(!_szFileName)
       return false;  _hFile =  CreateFile(
       _szFileName, 
       GENERIC_WRITE,
       FILE_SHARE_READ | FILE_SHARE_WRITE,
       NULL,
       OPEN_EXISTING,
       FILE_ATTRIBUTE_NORMAL,
       NULL 
      );  if(!IsOpen() && GetLastError() == 2)//打开不成功, 且因为文件不存在, 创建文件
       _hFile =  CreateFile(
        _szFileName, 
        GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL 
       );    if(IsOpen())
       SetFilePointer(_hFile, 0, NULL, FILE_END);  return IsOpen();
     } DWORD Write(LPCVOID lpBuffer, DWORD dwLength)
     {
      DWORD dwWriteLength = 0;  if(IsOpen())
       WriteFile(_hFile, lpBuffer, dwLength, &dwWriteLength, NULL);  return dwWriteLength;
     } virtual void WriteLog( LPCVOID lpBuffer, DWORD dwLength)//写日志, 可以扩展修改
     {
      time_t now;
      char temp[21];
      DWORD dwWriteLength;  if(IsOpen())
      {
       time(&now);
       strftime(temp, 20, "%Y-%m-%d %H:%M:%S", localtime(&now));   WriteFile(_hFile, "\xd\xa#-----------------------------", 32, &dwWriteLength, NULL);
       WriteFile(_hFile, temp, 19, &dwWriteLength, NULL);
       WriteFile(_hFile, "-----------------------------#\xd\xa", 32, &dwWriteLength, NULL);
       WriteFile(_hFile, lpBuffer, dwLength, &dwWriteLength, NULL);
       WriteFile(_hFile, "\xd\xa", 2, &dwWriteLength, NULL);
       
       FlushFileBuffers(_hFile);  }
     } void Lock()  { ::EnterCriticalSection(&_csLock); }
     void Unlock() { ::LeaveCriticalSection(&_csLock); }
     
    public:
      
     LogFile(const char *szFileName = "Log.log")//设定日志文件名
     {
      _szFileName = NULL;
      _hFile = INVALID_HANDLE_VALUE;
      ::InitializeCriticalSection(&_csLock);  SetFileName(szFileName);
     } virtual ~LogFile()
     {
      ::DeleteCriticalSection(&_csLock);
      Close();  if(_szFileName)
       delete []_szFileName;
     }
     
     const char * GetFileName()
     {
      return _szFileName;
     } void SetFileName(const char *szName)//修改文件名, 同时关闭上一个日志文件
     {
      ASSERT(szName);  if(_szFileName)
       delete []_szFileName;  Close();  _szFileName = new char[strlen(szName) + 1];
      ASSERT(_szFileName);
      strcpy(_szFileName, szName);
     } bool IsOpen()
     {
      return _hFile != INVALID_HANDLE_VALUE;
     } void Close()
     {
      if(IsOpen())
      {
       CloseHandle(_hFile);
       _hFile = INVALID_HANDLE_VALUE;
      }
     } void Log(LPCVOID lpBuffer, DWORD dwLength)//追加日志内容
     {
      ASSERT(lpBuffer);
      __try
      {
       Lock();   if(!OpenFile())
        return;   WriteLog(lpBuffer, dwLength);
      }
      __finally
      {
       Unlock();
      } 
     } void Log(const char *szText)
     {
      Log(szText, strlen(szText));
     }private://屏蔽函数 LogFile(const LogFile&);
     LogFile&operator = (const LogFile&);
    };class LogFileEx : public LogFile
    {
    protected: char *_szPath;
     char _szLastDate[9];
     int _iType; void SetPath(const char *szPath)
     {
      ASSERT(szPath);  WIN32_FIND_DATA wfd;
      char temp[MAX_PATH + 1] = {0};  if(FindFirstFile(szPath, &wfd) == INVALID_HANDLE_VALUE && CreateDirectory(szPath, NULL) == 0)
      {
       strcat(strcpy(temp, szPath), " Create Fail. Exit Now! Error ID :");
       ltoa(GetLastError(), temp + strlen(temp), 10);
       MessageBox(NULL, temp, "Class LogFileEx", MB_OK);
       exit(1);
      }
      else
      {
       GetFullPathName(szPath, MAX_PATH, temp, NULL);
       _szPath = new char[strlen(temp) + 1];
       ASSERT(_szPath);
       strcpy(_szPath, temp);
      }
     }public: enum LOG_TYPE{YEAR = 0, MONTH = 1, DAY = 2}; LogFileEx(const char *szPath = ".", LOG_TYPE iType = MONTH)
     {
      _szPath = NULL;
      SetPath(szPath);
      _iType = iType;
      memset(_szLastDate, 0, 9);
     } ~LogFileEx()
     {
      if(_szPath)
       delete []_szPath;
     } const char * GetPath()
     {
      return _szPath;
     } void Log(LPCVOID lpBuffer, DWORD dwLength)
     {
      ASSERT(lpBuffer);  char temp[10];
      static const char format[3][10] = {"%Y", "%Y-%m", "%Y%m%d"};
      
      __try
      {
       Lock();
       
       time_t now = time(NULL);   strftime(temp, 9, format[_iType], localtime(&now));   if(strcmp(_szLastDate, temp) != 0)//更换文件名
       {
        strcat(strcpy(_szFileName, _szPath), "\\");
        strcat(strcat(_szFileName, temp), ".log");
        strcpy(_szLastDate, temp);
        Close();
       }   if(!OpenFile())
        return;
       
       WriteLog(lpBuffer, dwLength);
      }
      __finally
      {
       Unlock();
      }
     } void Log(const char *szText)
     {
      Log(szText, strlen(szText));
     }private://屏蔽函数 LogFileEx(const LogFileEx&);
     LogFileEx&operator = (const LogFileEx&);};
    //#endif
      

  3.   

    以下是我分开的Log1.h
    // LogFile.h: interface for the LogFile class.
    //
    //////////////////////////////////////////////////////////////////////#if !defined(AFX_LOGFILE_H__ACA460F2_FA86_4C94_AC6B_7B7AA81F623A__INCLUDED_)
    #define AFX_LOGFILE_H__ACA460F2_FA86_4C94_AC6B_7B7AA81F623A__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    #ifndef _LOGFILE_H
    #define _LOGFILE_H
    #include <ASSERT.h>
    #include <time.h>
    #include <stdio.h>
    #include <windows.h>
    #include "stdafx.h"#ifdef DLL_FILE
    class _declspec(dllexport)LogFile //导出类LogFile
    #else
    class _declspec(dllimport)LogFile //导入类LogFile
    #endif  {
    protected: CRITICAL_SECTION _csLock;
     char * _szFileName;
     HANDLE _hFile; bool OpenFile();//打开文件, 指针到文件尾
     
     DWORD Write(LPCVOID lpBuffer, DWORD dwLength);
     
     void WriteLog( LPCVOID lpBuffer, DWORD dwLength);//写日志, 可以扩展修改
     void Lock() ;
     void Unlock() ;
     
    public:
      
     LogFile(const char *szFileName = "Log.log"); //设定日志文件名 ~LogFile();
     
     const char * GetFileName();
     
     void SetFileName(const char *szName); //修改文件名, 同时关闭上一个日志文件
     
     bool IsOpen();
     
     void Close();
     
     void Log(LPCVOID lpBuffer, DWORD dwLength) ; //追加日志内容
     void Log(const char *szText) ;
     
    private://屏蔽函数 LogFile(const LogFile&);
     LogFile&operator = (const LogFile&);};#endif#endif // !defined(AFX_LOGFILE_H__ACA460F2_FA86_4C94_AC6B_7B7AA81F623A__INCLUDED_)以下是我分开的Log1.cpp
    // LogFile.cpp: implementation of the LogFile class.
    //
    //////////////////////////////////////////////////////////////////////#include "stdafx.h"
    #include "LogFile.h"//////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////
    #ifndef DLL_FILE#define DLL_FILE#endif
    bool LogFile::OpenFile()  //打开文件, 指针到文件尾
     {
      if(IsOpen())
       return true;  if(!_szFileName)
       return false;  _hFile =  CreateFile(
       _szFileName, 
       GENERIC_WRITE,
       FILE_SHARE_READ | FILE_SHARE_WRITE,
       NULL,
       OPEN_EXISTING,
       FILE_ATTRIBUTE_NORMAL,
       NULL 
      );  if(!IsOpen() && GetLastError() == 2)//打开不成功, 且因为文件不存在, 创建文件
       _hFile =  CreateFile(
        _szFileName, 
        GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL 
       );    if(IsOpen())
       SetFilePointer(_hFile, 0, NULL, FILE_END);  return IsOpen();
     } DWORD LogFile::Write(LPCVOID lpBuffer, DWORD dwLength)
     {
      DWORD dwWriteLength = 0;  if(IsOpen())
       WriteFile(_hFile, lpBuffer, dwLength, &dwWriteLength, NULL);  return dwWriteLength;
     } void LogFile::WriteLog( LPCVOID lpBuffer, DWORD dwLength)//写日志, 可以扩展修改
     {
      time_t now;
      char temp[21];
      DWORD dwWriteLength;  if(IsOpen())
      {
       time(&now);
       strftime(temp, 20, "%Y-%m-%d %H:%M:%S", localtime(&now));   WriteFile(_hFile, "\xd\xa#-----------------------------", 32, &dwWriteLength, NULL);
       WriteFile(_hFile, temp, 19, &dwWriteLength, NULL);
       WriteFile(_hFile, "-----------------------------#\xd\xa", 32, &dwWriteLength, NULL);
       WriteFile(_hFile, lpBuffer, dwLength, &dwWriteLength, NULL);
       WriteFile(_hFile, "\xd\xa", 2, &dwWriteLength, NULL);
       
       FlushFileBuffers(_hFile);  }
     } void LogFile::Lock()  { ::EnterCriticalSection(&_csLock); }
     void LogFile::Unlock() { ::LeaveCriticalSection(&_csLock); }
     
    public:
      
     LogFile::LogFile(const char *szFileName = "Log.log")//设定日志文件名
     {
      _szFileName = NULL;
      _hFile = INVALID_HANDLE_VALUE;
      ::InitializeCriticalSection(&_csLock);  SetFileName(szFileName);
     } LogFile::~LogFile()
     {
      ::DeleteCriticalSection(&_csLock);
      Close();  if(_szFileName)
       delete []_szFileName;
     }
     
     const char * LogFile::GetFileName()
     {
      return _szFileName;
     } void LogFile::SetFileName(const char *szName)//修改文件名, 同时关闭上一个日志文件
     {
      ASSERT(szName);  if(_szFileName)
       delete []_szFileName;  Close();  _szFileName = new char[strlen(szName) + 1];
      ASSERT(_szFileName);
      strcpy(_szFileName, szName);
     } bool LogFile::IsOpen()
     {
      return _hFile != INVALID_HANDLE_VALUE;
     } void LogFile::Close()
     {
      if(IsOpen())
      {
       CloseHandle(_hFile);
       _hFile = INVALID_HANDLE_VALUE;
      }
     } void LogFile::Log(LPCVOID lpBuffer, DWORD dwLength)//追加日志内容
     {
      ASSERT(lpBuffer);
      __try
      {
       Lock();   if(!OpenFile())
        return;   WriteLog(lpBuffer, dwLength);
      }
      __finally
      {
       Unlock();
      } 
     } void LogFile::Log(const char *szText)
     {
      Log(szText, strlen(szText));
     }}
    编译时错误提示:--------------------Configuration: LogWin32 - Win32 Debug--------------------
    Compiling...
    LogFile.cpp
    E:\VC_XueXi\MyHis\LogWin32\LogFile.cpp(19) : warning C4273: 'OpenFile' : inconsistent dll linkage.  dllexport assumed.
    E:\VC_XueXi\MyHis\LogWin32\LogFile.cpp(54) : warning C4273: 'Write' : inconsistent dll linkage.  dllexport assumed.
    E:\VC_XueXi\MyHis\LogWin32\LogFile.cpp(64) : warning C4273: 'WriteLog' : inconsistent dll linkage.  dllexport assumed.
    E:\VC_XueXi\MyHis\LogWin32\LogFile.cpp(85) : warning C4273: 'Lock' : inconsistent dll linkage.  dllexport assumed.
    E:\VC_XueXi\MyHis\LogWin32\LogFile.cpp(86) : warning C4273: 'Unlock' : inconsistent dll linkage.  dllexport assumed.
    E:\VC_XueXi\MyHis\LogWin32\LogFile.cpp(88) : error C2143: syntax error : missing ';' before 'public'
    E:\VC_XueXi\MyHis\LogWin32\LogFile.cpp(91) : error C2572: 'LogFile::LogFile' : redefinition of default parameter : parameter 1
            e:\vc_xuexi\myhis\logwin32\logfile.h(44) : see declaration of 'LogFile::LogFile'
    E:\VC_XueXi\MyHis\LogWin32\LogFile.cpp(91) : warning C4273: 'LogFile::LogFile' : inconsistent dll linkage.  dllexport assumed.
    E:\VC_XueXi\MyHis\LogWin32\LogFile.cpp(100) : warning C4273: 'LogFile::~LogFile' : inconsistent dll linkage.  dllexport assumed.
    E:\VC_XueXi\MyHis\LogWin32\LogFile.cpp(109) : warning C4273: 'GetFileName' : inconsistent dll linkage.  dllexport assumed.
    E:\VC_XueXi\MyHis\LogWin32\LogFile.cpp(114) : warning C4273: 'SetFileName' : inconsistent dll linkage.  dllexport assumed.
    E:\VC_XueXi\MyHis\LogWin32\LogFile.cpp(115) : error C2065: 'ASSERT' : undeclared identifier
    E:\VC_XueXi\MyHis\LogWin32\LogFile.cpp(128) : warning C4273: 'IsOpen' : inconsistent dll linkage.  dllexport assumed.
    E:\VC_XueXi\MyHis\LogWin32\LogFile.cpp(133) : warning C4273: 'Close' : inconsistent dll linkage.  dllexport assumed.
    E:\VC_XueXi\MyHis\LogWin32\LogFile.cpp(142) : warning C4273: 'Log' : inconsistent dll linkage.  dllexport assumed.
    E:\VC_XueXi\MyHis\LogWin32\LogFile.cpp(160) : warning C4273: 'Log' : inconsistent dll linkage.  dllexport assumed.
    E:\VC_XueXi\MyHis\LogWin32\LogFile.cpp(164) : error C2143: syntax error : missing ';' before '}'
    E:\VC_XueXi\MyHis\LogWin32\LogFile.cpp(164) : error C2143: syntax error : missing ';' before '}'
    E:\VC_XueXi\MyHis\LogWin32\LogFile.cpp(164) : error C2143: syntax error : missing ';' before '}'
    Error executing cl.exe.LogFile.obj - 6 error(s), 13 warning(s)