hur.cn - 华软网

 热门搜索

有谁会用CXImage类啊 求指导!!!

  作者:未知    来源:网络    更新时间:2011/3/30
我弄了好久了  就是在网上把cximage 下下来后 就配置 :
1。先编译所有的。dsw
2.将所有的。dsp 添加到我的工程workspace下
3.在工程里面dependces 打勾  在工程的setting中 将c/c++ code genaeration use run-time library  multithreaded DLL
  Precomplied Headers 选NOT using precomplied headers   然后在 Additional include directories 下添加什么啊? 是哪个文件的路径?
4.在刚才里添加 #include “cximage.h”
编译出错 有31个错误 说是找不到路径 
纠结死我了  教我啊!!!
---华软 网友回答---
没人顶我自己顶 求高手指导啊
---华软网友回复---
Additional include directories中添加cximage的include目录,还要在lib中添加cximage的lib。
---华软网友回复---
C++">日志文件应具备基本功能
Log4j据说是最闻名的日志文件类库,有针对于C++或者.NET的移植版本。一直不明白日志文件有什么特殊之处,也没有研究其功能强大在何处。

理想中的日志文件类库功能应该具备:一个中心、两项基本功能、三个补充要求! 
一个中心点:    使用简单
就是使用的时候可以感觉日志功能是随插随用,不用在代码层次上做太多前期的步骤。 
两个基本功能:日志类型管理、日志文件管理
        日志类型管理包括:格式化输出、日期时间标记等。前者可以考虑为日志分类,后者带上时间标记便于跟踪调试分析。
        日志文件管理包括:日志文件的大小约定、按时间段整理等 
三点补充要求:多种类型信息输出、多个进程输出到同一个日志文件、多进程线程同时输出时互斥操作 
以下是根据在实际过程中的运用,封装一个简单的日志文件功能模块。麻雀虽小,但是却满足以上所有要求。其中,对于日志文件管理这块简单点约定输出到指定文件名。

由于采用CString,因此仅适用于MFC!但是可以方便的改造为纯C|C++

//===============================================================// LOG::简单的日志工具// 日志功能包应该包括以下两块功能:// 1. 每个日志文本串// 目前日志文本串包括 [prefix][datetime][type][info...]// a.多个进程输出到同一个日志文件,可通过prefix来区分每个进程; 可以忽略// b.datetime可以用来测试时间// c.类型可以设定[error|warn|debug],// 由使用者任意使用,并不做明确标记; 也可以忽略// d.info,可以根据实际情况任意格式化输出,类似printf// 2. 日志文件// a. 可将日志串保存到文本,或者自己处理// b. 支持并发写操作// c. 日志文件的管理//=============================================================== 

--------------------------------------------------------------------------------

.h文件
class LOG{public:LOG();virtual ~LOG(); public://-日志文件-//----如果没有指定,则为exe所在路径下的log.log文件----static CString GetLogFile();static short SetLogFile(LPCTSTR strPath);static short ViewLogFile(); //-前缀-//----如果多个进程往同一个文件输出日志,可以为每个进程设置一个前缀----//----前缀出现在日期时间之前----static short SetPrefix(LPCTSTR strPrefix); //-日志信息-//-获取日志字符串,可以另外-static CString sOutV(LPCTSTR strType, LPCTSTR strFormat = NULL, va_list valist = NULL);static CString sOut0(LPCTSTR strType, LPCTSTR strFormat = NULL,...);static CString sOut ( LPCTSTR strFormat = NULL,...); //-将日志信息输出到文件-static short OutV(LPCTSTR strType, LPCTSTR strFormat = NULL, va_list valist = NULL);static short Out0(LPCTSTR strType, LPCTSTR strFormat = NULL,...);static short Out (LPCTSTR strFormat = NULL,...); protected:static CString s_strLogFile;static CString s_strLogPrefix;static HANDLE s_hWriteEvent;}; 

--------------------------------------------------------------------------------

.cpp文件
// 得到可执行程序所在目录// BOOL bIncludeSep -- 是否包含最后的分隔符"\"CString GetExePath(BOOL bIncludeSep){// 得到当前的文件名CString strFileName;GetModuleFileName(AfxGetInstanceHandle(),strFileName.GetBuffer(_MAX_PATH),_MAX_PATH);strFileName.ReleaseBuffer();// 得到当前目录strFileName=strFileName.Left(strFileName.ReverseFind(_T('\\'))+1); if(bIncludeSep)return strFileName;elsereturn strFileName.Left(strFileName.GetLength()-1);} //-获取最后的文件名 如果给定文件不是全路径,就是相对于exe-CString GetFileForExePath(LPCTSTR strCurFileName){CString strPath = strCurFileName;if(!strPath.IsEmpty()){//-相对路径-if(strPath.Find(_T(":"))<=0) { strPath.Format(_T("%s%s"), GetExePath(FALSE), strCurFileName);    } } return strPath; }  #define LOG_EVENT _T("ChyLogWrite") CString LOG::s_strLogFile = _T(""); CString LOG::s_strLogPrefix = _T(""); HANDLE LOG::s_hWriteEvent = NULL;  LOG::LOG() {}  LOG::~LOG() {}  short LOG::SetLogFile(LPCTSTR strPath){if(strPath==NULL || strPath[0]==0)s_strLogFile = GetFileForExePath("log.log");elses_strLogFile = GetFileForExePath(strPath); return 1;} CString LOG::GetLogFile(){return s_strLogFile;} short LOG::ViewLogFile(){CString strLogFile = GetLogFile();ShellExecute(NULL, _T("open"), strLogFile, NULL, NULL, SW_SHOW);return strLogFile.IsEmpty()?0:1;} short LOG::SetPrefix(LPCTSTR strPrefix){if(strPrefix && strPrefix[0]){s_strLogPrefix = strPrefix;} return 1;} CString LOG::sOutV(LPCTSTR strType, LPCTSTR strFormat, va_list valist){ CString strPart_Prefix;if(!s_strLogPrefix.IsEmpty()){strPart_Prefix.Format(_T("[%s]"), s_strLogPrefix);} CString strPart_Time;{SYSTEMTIME sysTime = {0};GetLocalTime(&sysTime);strPart_Time.Format(_T("[%2d-%2d %2d:%2d:%2d_%3d]"), sysTime.wMonth, sysTime.wDay, sysTime.wHour, sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds); } CString strPart_Type;if(strType && strType[0]){strPart_Type.Format(_T("[%s]"), strType);} CString strPart_Info;{ strPart_Info.FormatV(strFormat, valist);} CString str = strPart_Prefix + strPart_Time + strPart_Type+ strPart_Info; return str;} CString LOG::sOut0(LPCTSTR strType, LPCTSTR strFormat,...){va_list valist;va_start(valist, strFormat); CString strInfo = sOutV(strType, strFormat, valist);va_end(valist);  return strInfo;} CString LOG::sOut(LPCTSTR strFormat,...){va_list valist;va_start(valist, strFormat);CString strInfo = sOutV(NULL, strFormat, valist);va_end(valist); return strInfo;}  short LOG::OutV(LPCTSTR strType, LPCTSTR strFormat, va_list valist){//--if(s_hWriteEvent==NULL){s_hWriteEvent = OpenEvent(0, FALSE,LOG_EVENT);if(s_hWriteEvent==NULL)s_hWriteEvent = CreateEvent(NULL, FALSE, TRUE, LOG_EVENT); } WaitForSingleObject(s_hWriteEvent, INFINITE); //-打开关闭文件-if(s_strLogFile.IsEmpty())SetLogFile(NULL);CStdioFile file;if(file.Open(s_strLogFile, CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite)){CString strPart_NewLine = _T("\n");CString strInfo = sOutV(strType, strFormat, valist); CString str = strPart_NewLine + strInfo; file.SeekToEnd();file.WriteString(str);file.Close();} SetEvent(s_hWriteEvent); return 1;} short LOG::Out0(LPCTSTR strType, LPCTSTR strFormat,...){va_list valist;va_start(valist, strFormat); short rtn = OutV(strType, strFormat, valist);va_end(valist); return rtn;} short LOG::Out(LPCTSTR strFormat,...){va_list valist;va_start(valist, strFormat);short rtn = OutV(NULL, strFormat, valist);va_end(valist); return rtn;} 

--------------------------------------------------------------------------------

使用说明
  //-设定日志文件,建议在Exe初始化时设定-//-设置相对路径则表示exe所在路径下-//-如果不设定则为exe所在路径下的log.log文件-LOG::SetLogFile("bbb.log");  //-获取日志文本串,可以自行处理,例如输出到界面-CString str;str = LOG::sOut0("debug", "hello");str = LOG::sOut0("warn5", "hello %d", 25);str = LOG::sOut0("warn3", "hello %s, you have %d apples!", "libai", 10);str = LOG::sOut ("hello %s, you have %d apples!", "libai", 10); //-输出到文件-LOG::Out0("debug", "hello");LOG::Out0("warn5", "hello %d", 25);LOG::Out0("warn3", "hello %s, you have %d apples!", "libai", 10);LOG::Out ("hello %s, you have %d apples!", "libai", 10); //-查看日志文件-LOG::ViewLogFile();

---华软网友回复---



/*Windows Mobile下使用Native C++开发日志类 
背景
这段业余时间一直都在开发iToday。在iToday中加入日志管理。关于iToday,可以参考那些一些文章。
开源(Open Source)那些事儿 (一)
开源那些事儿 (二) - iToday开源项目计划
开源那些事儿(三)-iToday的总体设计
开源那些事儿(四)-如何使用CodePlex进行项目管理
简介
日志管理是程序不可以缺少的一个重要组成部分,对于长期运行的后台程序尤为重要,尽管经过了大量的测试,
但是在实际运行环境下,程序未免有出错的时候。有时候由于第三方原因导致的,例如电信网络质量下载,掉包等等。
在一些看似莫名其妙的问题下,日志文件很多时候就成了救命绳。bug free是我们一直追求的目标,但是我永远不能保证bug free,
每次我在面试中说这句话,做****出生的人会翻白眼,做技术的人会会心一笑。我能保证的是如何尽快的troubleshooting,
提高质量,日志文件在这过程中又是最重要的手段之一。
下面文章讲述使用Native C++对Windows Embedded CE和Windows Mobile日志文件类的封装代码先上代码,下面分析。
需要iToday全部代码也可以到codeplex上去下载
类定义文件*/


typedef enum tagLOG_LEVEL
{
    LOG_TRACE,    //跟踪
    LOG_INFO,     //报告
    LOG_WARNING,  //警告
    LOG_ERROR,    //错误
    LOG_FATAL,    //严重错误
    LOG_NONE = 10,//没错误
}LOG_LEVEL;

class Logger
{
public:
    static Logger& Instance();
    
    static void SetLogFilePath( const std::string& strFilePath);
    static void SetLogLevel( const LOG_LEVEL enLogLevel);


---华软网友回复---

 //va_list在win32/vc++6.0下的讨论



1.  简介

va_list、va_arg、va_end是为了处理变参数的函数而做的宏定义,这些定义会因为平台(cpu、操作系统
)和环境(编译系统)的不同而有所不同。

简单原理:编译系统编译时,会将函数的参数依次放到栈中,这样根据固定参数的地址以及固定参数给出的相
关信息很容易得到可变参数的个数、类型、值。注意一点,这些或者是固定参数给出的信息,虽然不是直接给出的
;或者是程序写作者自我约定。得到了可变参数,剩下的处理和普通函数一样了。

以下的理解和实例均在win32&vc++6.0环境中的情况。

2.  结合一个实例看简单原理

实例如下(win2kserver vc++6.0编译通过):

//============================

//求若干个整数的平均值

#include 

#include 

 

int AveInt(int,...);

 

void main()

{

       printf("%d\t",AveInt(2,2,3));

       printf("%d\t",AveInt(4,2,4,6,8));

       return;

}

 

int AveInt(int num,...)

{

       int ReturnValue=0;

       int i=num;

       va_list myvalist;

       va_start(myvalist,num);

       while(i>0)

       {

              ReturnValue+=va_arg(myvalist,int);

              i--;

       }

       return ReturnValue/=num;

}

//===============================

(1)       分配情况:跟第二次调用AveInt(4,2,4,6,8),看下参数在内存中的分配,见下图。



 

图1

明显,参数依次连续分配;

(2)       参数的个数:由第一个参数给定;

(3)       参数类型:我约定为整数;

(4)       参数值:明显了。

3.  两个小知识(自我整理下)

(1)       win32 vc++编译

内存分配由高址向低址进行;参数调用时,参数入栈顺序:从最后一个开始,直到第一个。通过上图可以看到这两点。

(2)       内存对齐

分为结构成员内存对齐和栈内存对齐。

前者要求:字、双字和四字在自然边界上不需要在内存中对齐。
(对字、双字和四字来说,自然边界分别是偶数地址、可以被4整除的地址、和可以被8整除的地址。)
一个字或双字操作数跨越了4字节边界,或者一个四字操作数跨越了8字节边界,被认为未对齐的。

后者要求:总保持对齐,而且对齐在4字节边界上。

两者区别:前者是可以通过工具控制对齐边界的,如在vc++中就可以通过控制选项控制边界;
而后者是不能控制的,必须对齐的,毕竟栈的效率太影响到程序性能了。

4.  宏定义

以下是vc++6.0定义在stdarg.h文件中的关于x86平台的部分宏定义:

typedef char *  va_list;

#define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )

#define va_start(ap,v)  ( ap = (va_list)&v + _INTSIZEOF(v) )

#define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )

#define va_end(ap)      ( ap = (va_list)0 )

结合上例,调用AveInt(4,2,4,6,8),当运行了va_start(myvalist,num);
之后,根据定义myvalist =(va_list)&num+_INTSIZEOF(i),这样myvalist指向第一个可变参
数2;第一次运行va_arg(myvalist,int);后,先让myvalist+= _INTSIZEOF(int)指向下一个可变参
数4,然后在取出前面的可变参数2进行处理;依此类推。
     
华软声明:本内容来自网络,如有侵犯您版权请来信指出,本站立即删除。