2008年3月20日星期四

C++ Linux 中mencpy(),get(),strcpy(),strcmp()....的函数原型

1 /*
2 * linux/lib/string.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
6
7 /*
8 * stupid library routines.. The optimized versions should generally be found
9 * as inline code in
10 *
11 * These are buggy as well..
12 */
13
14 #include
15
16 char * ___strtok = NULL;
17
18 char * strcpy(char * dest,const char *src)
19 {
20 char *tmp = dest;
21
22 while ((*dest++ = *src++) != '\0')
23 /* nothing */;
24 return tmp;
25 }
26
27 char * strncpy(char * dest,const char *src,size_t count)
28 {
29 char *tmp = dest;
30
31 while (count-- && (*dest++ = *src++) != '\0')
32 /* nothing */;
33
34 return tmp;
35 }
36
37 char * strcat(char * dest, const char * src)
38 {
39 char *tmp = dest;
40
41 while (*dest)
42 dest++;
43 while ((*dest++ = *src++) != '\0')
44 ;
45
46 return tmp;
47 }
48
49 char * strncat(char *dest, const char *src, size_t count)
50 {
51 char *tmp = dest;
52
53 if (count) {
54 while (*dest)
55 dest++;
56 while ((*dest++ = *src++)) {
57 if (--count == 0)
58 break;
59 }
60 }
61
62 return tmp;
63 }
64
65 int strcmp(const char * cs,const char * ct)
66 {
67 register signed char __res;
68
69 while (1) {
70 if ((__res = *cs - *ct++) != 0 || !*cs++)
71 break;
72 }
73
74 return __res;
75 }
76
77 int strncmp(const char * cs,const char * ct,size_t count)
78 {
79 register signed char __res = 0;
80
81 while (count) {
82 if ((__res = *cs - *ct++) != 0 || !*cs++)
83 break;
84 count--;
85 }
86
87 return __res;
88 }
89
90 char * strchr(const char * s,char c)
91 {
92 for(; *s != c; ++s)
93 if (*s == '\0')
94 return NULL;
95 return (char *) s;
96 }
97
98 size_t strlen(const char * s)
99 {
100 const char *sc;
101
102 for (sc = s; *sc != '\0'; ++sc)
103 /* nothing */;
104 return sc - s;
105 }
106
107 size_t strnlen(const char * s, size_t count)
108 {
109 const char *sc;
110
111 for (sc = s; *sc != '\0' && count--; ++sc)
112 /* nothing */;
113 return sc - s;
114 }
115
116 size_t strspn(const char *s, const char *accept)
117 {
118 const char *p;
119 const char *a;
120 size_t count = 0;
121
122 for (p = s; *p != '\0'; ++p) {
123 for (a = accept; *a != '\0'; ++a) {
124 if (*p == *a)
125 break;
126 }
127 if (*a == '\0')
128 return count;
129 ++count;
130 }
131
132 return count;
133 }
134
135 char * strpbrk(const char * cs,const char * ct)
136 {
137 const char *sc1,*sc2;
138
139 for( sc1 = cs; *sc1 != '\0'; ++sc1) {
140 for( sc2 = ct; *sc2 != '\0'; ++sc2) {
141 if (*sc1 == *sc2)
142 return (char *) sc1;
143 }
144 }
145 return NULL;
146 }
147
148 char * strtok(char * s,const char * ct)
149 {
150 char *sbegin, *send;
151
152 sbegin = s ? s : ___strtok;
153 if (!sbegin) {
154 return NULL;
155 }
156 sbegin += strspn(sbegin,ct);
157 if (*sbegin == '\0') {
158 ___strtok = NULL;
159 return( NULL );
160 }
161 send = strpbrk( sbegin, ct);
162 if (send && *send != '\0')
163 *send++ = '\0';
164 ___strtok = send;
165 return (sbegin);
166 }
167
168 void * memset(void * s,char c,size_t count)
169 {
170 char *xs = (char *) s;
171
172 while (count--)
173 *xs++ = c;
174
175 return s;
176 }
177
178 char * bcopy(const char * src, char * dest, int count)
179 {
180 char *tmp = dest;
181
182 while (count--)
183 *tmp++ = *src++;
184
185 return dest;
186 }
187
188 void * memcpy(void * dest,const void *src,size_t count)
189 {
190 char *tmp = (char *) dest, *s = (char *) src;
191
192 while (count--)
193 *tmp++ = *s++;
194
195 return dest;
196 }
197
198 void * memmove(void * dest,const void *src,size_t count)
199 {
200 char *tmp, *s;
201
202 if (dest <= src) {
203 tmp = (char *) dest;
204 s = (char *) src;
205 while (count--)
206 *tmp++ = *s++;
207 }
208 else {
209 tmp = (char *) dest + count;
210 s = (char *) src + count;
211 while (count--)
212 *--tmp = *--s;
213 }
214
215 return dest;
216 }
217
218 int memcmp(const void * cs,const void * ct,size_t count)
219 {
220 const unsigned char *su1, *su2;
221 signed char res = 0;
222
223 for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
224 if ((res = *su1 - *su2) != 0)
225 break;
226 return res;
227 }
228
229 /*
230 * find the first occurrence of byte 'c', or 1 past the area if none
231 */
232 void * memscan(void * addr, unsigned char c, size_t size)
233 {
234 unsigned char * p = (unsigned char *) addr;
235
236 while (size) {
237 if (*p == c)
238 return (void *) p;
239 p++;
240 size--;
241 }
242 return (void *) p;
243 }

20.03.2008 Aufgabe: Exclusiv Connection Access DB with Ado

1. Korrektur von Access Dantenbank verbindung mit Ado.Um Exception von DB_Close() zu überwinden,vor "if ( m_pADOpaelogbuch->bConnectionIsOpen() )" addiere "if (m_pADOpaelogbuch != NULL)", erst prüft mal die Abwesenheit der Pointobjekte "m_pADOpaelogbuch":

if (m_pADOpaelogbuch != NULL)
{

if ( m_pADOpaelogbuch->bConnectionIsOpen() )
{

if( m_pADOpaelogbuch->CloseRecordsetAdoDB() ||
m_pADOpaelogbuch->CloseConnections() )
{

delete m_pADOpaelogbuch;
m_pADOpaelogbuch = NULL;
error = NOT_ERROR;

}
else
{
error = ADO_DISCONNECT_ERROR;

}

}else
{
AddStringError((LPCTSTR)(CString("connect from paelogbuch to ") + plc.tgDB + CString(" has not been opend.")) );
error = ADO_CONNECT_ERROR;
}

}


2. Bei DB_Open():

if (!( m_pADOpaelogbuch = new ADOpaelogbuch((LPCTSTR)plc.tgDB) ))
{

error = ADO_CONNECT_ERROR;

}

ist "if (!( m_pADOpaelogbuch = new ADOpaelogbuch((LPCTSTR)plc.tgDB) ))" ungültig, weil "ADOpaelogbuch(tgDB)" kein returned Value.
Codes:

//////////////////////////////////////////////////////////////////////
// *
// * Editor: zengzn@gmail.com 20.03.2008
// * after testing is known, that "CAdoExternDB *m_pExternDB;"
// * makes m_pExternDB not NULL, exceptions will only been thrown by
// * "m_pExternDB->bConnectionIsOpen()" if "new CAdoExternDB((LPCTSTR)sDB,nMode)"
// * tries to connect a unexsiting file.
// * It does not matter if the exlusive connection fails
// * or opens a wrong file(.txt or others), no exception throws out.
// *
//////////////////////////////////////////////////////////////////////
if (plc.existFile(sDB))
{

m_pExternDB = new CAdoExternDB( (LPCTSTR)sDB, nMode );
if (m_pExternDB != NULL)
{

if (m_pExternDB->bConnectionIsOpen() )

error = NOT_ERROR;

else

error = ADO_CONNECT_ERROR;


}
else

error = ADO_CONNECT_ERROR;


}
else
{

error = OPEN_FILE_FAILED;

}

3. Exclusive connection to Access DB with Ado:
in ADOBase.cpp:

OpenAdoDB(AdoNs::_ConnectionPtr& pConnDB, const char* sDatabasePath, AdoNs::ConnectModeEnum nMode)
...
pConnDB->Mode = nMode;

nMode can be:

msado15.tlh
enum ConnectModeEnum
{

adModeUnknown = 0,
adModeRead = 1,
adModeWrite = 2,
adModeReadWrite = 3,
adModeShareDenyRead = 4,
adModeShareDenyWrite = 8,
adModeShareExclusive = 12,
adModeShareDenyNone = 16,
adModeRecursive = 4194304

};


4. Versuche die Möglichkeit die DB Einspielung mit ADO-Exclusive Connection,wenn andere Client verbindung nach DB-Server hat, warte mal kurz(1 min ? ) und versucht nochmal, sonst "adModeUnknown" und alert den Benutzer ob weiter geht.

2008年3月19日星期三

Fehler Meldung bei unpack.exe (1)




Vermutliche Fehlerpunte:
Bei remote access von ferner Client kann diese Fehler erscheinen. Weil die Pfad"C:\Dokumente und Einstellung\LocalService\Desktop" enthält kein Benutzer, welche Benutzer-name kann auf remote computer eingelogen? anonymouse? Guest? oder "LocalService"?


Mögliche Lösung:

in Public.cpp add:

CPublic::CPublic()
{

...
CPublic::sSicherungDir = ( ( CPublic::sSicherungDir == _T("") || !existsDir(CPublic::sSicherungDir) ) ? _T("C:\\") : CPublic::sSicherungDir );

}


in CUnpackView.cpp CALLBACK CUnpackView::BrowseCallbackProc() ändert:

////////////////////////////////////////////////////////
//'d:\\' can not be recognised by SHGetPathFromIDList()
// must be changed into 'd:\'
////////////////////////////////////////////////////////
dir.Replace("\\\\","\\");
...
switch(uMsg)
{
case BFFM_INITIALIZED: //initial
hasInitial =true;
::SendMessage(hwnd,BFFM_SETSELECTION,TRUE,(LPARAM)(LPCTSTR)dir ); //"d:\\datenversicherung"
//AfxMessageBox("BFFM_INITIALIZED");

break;

case BFFM_SELCHANGED: //path changed
{
/////////////////////////////////////////////////////
// * modified by zengzn@gmail.com on 14.03.08
// * to avoid SHGetPathFromIDList()twice running
// * before "case BFFM_INITIALIZED" has been done
/////////////////////////////////////////////////////
if (hasInitial)
{
char curr[MAX_PATH];

SHGetPathFromIDList((LPCITEMIDLIST)lParam,curr);

//CString s;
//s.Format("BFFM_SELCHANGED, curr: %s",curr);
//AfxMessageBox(s);

if(curr[strlen(curr)-1]==92)
sprintf(curr,"%s",curr);
else
sprintf(curr,"%s\\",curr);

::SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)curr);

}

}
break;



2008年3月13日星期四

VC++: Accelerator 快捷键

In datei Project.rc:
Mansche wenn Projekte Verzeichniss direkt kopiert aus war, könnte diese Accelerator disable sein. Die lösung ist so wie ""C",ID_EDIT_COPY,..." auszukommentieren.

/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//

IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE
BEGIN
"N", ID_FILE_NEW, VIRTKEY,CONTROL
"O", ID_FILE_OPEN, VIRTKEY,CONTROL
"S", ID_FILE_SAVE, VIRTKEY,CONTROL
"P", ID_FILE_PRINT, VIRTKEY,CONTROL
"Z", ID_EDIT_UNDO, VIRTKEY,CONTROL
"X", ID_EDIT_CUT, VIRTKEY,CONTROL
"C", ID_EDIT_COPY, VIRTKEY,CONTROL
"V", ID_EDIT_PASTE, VIRTKEY,CONTROL
VK_BACK, ID_EDIT_UNDO, VIRTKEY,ALT
VK_DELETE, ID_EDIT_CUT, VIRTKEY,SHIFT
VK_INSERT, ID_EDIT_COPY, VIRTKEY,CONTROL
VK_INSERT, ID_EDIT_PASTE, VIRTKEY,SHIFT
VK_F6, ID_NEXT_PANE, VIRTKEY
VK_F6, ID_PREV_PANE, VIRTKEY,SHIFT
END

2008年3月7日星期五

软件2.0概念图

使用静态变量提高performance

In Project Unpack, die "CPublic plc" will be called for many times, each calling will run "CPublic::CPublic()" once. It takes a lot of rumtime to intial again and again those variables in "CPublic::CPublic()".

The solusion is: define these varables as static, so once "CPublic::CPublic()" be call, these variables will be valued. Next time will not be valued again.

codes:

public.h

static CString sInstallDir;
static CString sApoWorkDir;
static CString sSicherungDir;
static CString sVersionA3000;

static int nDBError;
static int nADOError;
static int nVersionA3000;


public.cpp

CString CPublic::sInstallDir =_T("");
CString CPublic::sApoWorkDir =_T("");
CString CPublic::sSicherungDir =_T("");
CString CPublic::sVersionA3000 =_T("");
int CPublic::nDBError = NOT_ERROR;
int CPublic::nADOError = NOT_ERROR;
int CPublic::nVersionA3000 = NOT_ERROR;
//********************************************************************************************
CPublic::CPublic()
{
//AfxMessageBox("call public!");

sDBError = _T("");
sADOError = _T("");
//nDBError = NOT_ERROR; //otherweise the valud is default with 1598884628
//nADOError = NOT_ERROR;
sSicherungDBError = _T("");
nSicherungDBError = NOT_ERROR;
nA3queryErrorLevel = 0;
sDaSiLaufwerk =_T("");
sPaeDatDir =_T("");

bReclaimDirProtect = false;

///////////////////////////////////////////////////////////////
//
// * to avoid reloading of some functions in CPublic::CPublic()
// * by checking the value of these static variable
//
///////////////////////////////////////////////////////////////
if (CPublic::sInstallDir.IsEmpty())
CPublic::sInstallDir = (LPCTSTR)m_reg.GetRegInstallDir(); //A3000 install dir C:\\A3000

sRezepturDir = "C:\\Rezeptur"; //valude in CUnpackView::OnCheckRezeptur()

sSourceDB = (LPCTSTR)((CPublic::sInstallDir) + CString("\\Database\\Apollo.mdb"));

//static
//---- * open apllo.mdb to get the parameter : sichrungdir
if (CPublic::sVersionA3000.IsEmpty())
{
CPublic::nDBError = openDB(); //sourceDB! get the version info
//get version info from apollo.mdb table version
CPublic::nVersionA3000 = m_versionA3000.m_versionsnummer;
CPublic::sVersionA3000.Format("%d", CPublic::nVersionA3000);
//CString s;
//s.Format("%d",m_version.m_versionsnummer);
//AfxMessageBox(s);
closeDB();
}
//---- *

//static
//---- *
if (CPublic::sSicherungDir.IsEmpty())
{
CPublic::nADOError = ADO_openDB();
//Get sicherungDir from regedit else apollo.mdb
CPublic::sSicherungDir = m_reg.GetRegDasiPath();
CPublic::sSicherungDir = ( ( CPublic::sSicherungDir == _T("") || !existsDir(CPublic::sSicherungDir) ) ? sDaSiLaufwerk : CPublic::sSicherungDir );
}

//static
//sApoWorkDir not allowed be null or folder not exists
if (CPublic::sApoWorkDir.IsEmpty())
{
CPublic::sApoWorkDir = ( sPaeDatDir == _T("") ? _T("C:\\Apo_Work") : sPaeDatDir );
mdDirectory(CPublic::sApoWorkDir);
}
//---- *




//AfxMessageBox(sApoWorkDir);
if(!CPublic::sInstallDir.IsEmpty())
{
sReportUrl = (LPCTSTR) ((CPublic::sInstallDir) + CString("\\Sicherungsentpacken_report.txt"));
sA3query = (LPCTSTR) ((CPublic::sInstallDir) + CString("\\a3query"));
sA3info = (LPCTSTR) ((CPublic::sInstallDir) + CString("\\A3info"));
sTool = (LPCTSTR) ((CPublic::sInstallDir) + CString("\\tool"));
sA3Task = (LPCTSTR) ((CPublic::sInstallDir) + CString("\\A3Task"));
sA3000bat = (LPCTSTR) ((CPublic::sInstallDir) + CString("\\a3000.bat"));
sJournalBat = (LPCTSTR) ((CPublic::sInstallDir) + CString("\\Journal.bat"));
sJDcomInfo = (LPCTSTR) ((CPublic::sInstallDir) + CString("\\jdcom_information"));
sJDcomApo = (LPCTSTR) ((CPublic::sInstallDir) + CString("\\jdcom_apotheke"));
//sTgDB = (LPCTSTR) (InstallDir + CString("\\Database\\Apollo.mdb"));
//ATISERV = (LPCTSTR) (InstallDir + CString("\\ATIServ"));
//ALifeService = (LPCTSTR) (InstallDir + CString("\\ALifeService"));
}


sA3000BatProtocolFile = "C:\\_A3000_BAT_PROTOKOLL.txt";
sJournalBatProtocolFile = "C:\\_JOURNAL_BAT_journal_PROTOKOLL.txt";


}


in other classes
will be call as "CPublic::sInstallDir" but not "plc.sInstallDir"

在MFC下定义全局变量和全局函数

用MFC制作的工程由很多文件构成,它不能象一般C++程序那样随意在类外定义全局变量,在这里要想定义能被工程内多个文件共享的全局变量和函数必须用一些特殊方法才行。实际上有多种方法可以实现,这里只介绍两种方法。

  一、在应用程序类中定义

  用MFC生成的工程中都有一个名为CxxxApp的类,它派生于CWinApp类。这个类主要进行程序的初始化,生成文档、视图对象等工作。我们可以把需要全局访问的变量和函数定义为这个类的成员变量和成员函数,就可以实现全局访问了。

  从严格意义上讲,这种变量和函数并不是全局的,因为它仍然只是类中的成员,只是由于我们很容易获得CxxxApp类的指针,所以我们可以在文档、视 图、对话框以及各种自定义类中访问到它们,达到与全局变量类似的效果。访问时用函数“AfxGetApp()”获得CxxxApp类的指针,用 “AfxGetApp()->成员”访问变量或函数。

  例:

  Test.h:(应用程序类头文件)

class CTestApp : public CWinApp
{
 public:
  int x; //全局变量
  int f(int y); //全局函数
  …………
};

  Test.cpp:(应用程序类程序文件)

int CTestApp::f(int y) //全局函数定义
{
 y++;
 return y;
}

  定义在CTestApp类中的变量和函数可以在其它类中被访问。比如在视图的某函数中要访问变量x和函数f():

void CTestView::xyz()
{
 CTestApp *app = (CTestApp *)AfxGetApp(); //生成指向应用程序类的指针
 app->x = 0; //访问变量x
 int z = app->f(1); //访问函数f()
 …………
}

  这样,变量x和函数f()可以视作为全局的。

  用这种方法实现的全局变量和全局函数虽比较简单,但也有缺点,一是访问不太方便,每次都需要获取应用程序类的指针;再就是把一些与应用程序类本身无关的变量和函数放在里面,使这个类看上去怪怪的,破坏了类的封装。

  二、用静态变量和静态函数实现

  很喜欢API函数的那种调用方法,不论在哪个类中只要用“::API函数”就可以调用了。合理利用静态类型(static)可以实现与此相似的全局变量和全局函数。

  静态变量和静态函数有如下性质:

  若在一个类中用关键字static声明数据成员,则这个数据成员就只存在一个拷贝,无论该类创建了多少个实例,它始终只存在一个,即使该类的实例一个也没创建,它也存在。

  若在一个类中用关键字static声明函数,该函数可以用“类名::函数名”方式访问,无需引用该类的实例,甚至这个类的实例可以不存在。

  利用这个性质实现的全局变量和函数使用起来很方便。

  值得注意的是,全局变量和全局函数最好集中封装,不要在文档、视图等类内部定义,这样用起来才有全局的感觉。

  例:

  1、添加一个没有基类的新类,设类名起为CPublic,姑且称之为公用类

  单击“Insert”菜单下的“New Class”命令,选择“Class type”为“Generic Class”,在“Name”栏中填入类名“CPublic”,单击“OK”,则新类建立完毕。

  2、包含公用类的头文件,使各个类都能访问它

  CPublic的头文件应包含在应用程序类的头文件中,这样在其它类中引用CPublic类时就不需要再包含了。

  Test.h:(应用程序类头文件)

#include "Public.h" //包含公用类头文件

class CTestApp : public CWinApp
{
…………
};

  3、在公用类中定义全局变量和全局函数,均使用static修饰,静态变量还必须在类外定义和初始化

  Public.h:(公用类头文件)

class CPublic
{
public:
CPublic();
virtual ~CPublic();

public:
static int x; //全局变量
static int time; //全局变量
static int f(int y); //全局函数
…………
}

  在公用类中对静态变量进行初始化和定义函数体:

  Public.cpp:(公用类程序文件)

int CPublic::x = 0; //初始化全局变量
int CPublic::time; //定义全局变量

CPublic::CPublic()
{

}

CPublic::~CPublic()
{

}

int CPublic::f(int y) //全局函数,这里不要再加static
{
y++;
return y;
}

  4、全局量的使用

  使用变量:CPublic::变量名

  使用函数:CPublic::函数()

  如在视图的某函数中访问变量x和函数f():

void CTestView::xyz()
{
CPublic::x = 0; //访问变量x
CPublic::time = CPublic::f(1); //访问函数f()
…………
}

  在其它类中访问x、time和f()的方法与此相同。

  5、几点注意:

  ① 由于静态量可独立于类存在,不需要生成CPublic类的实例。

  ② 静态数据成员的定义和初始化必须在类外进行,如例中x的初始化;变量time虽然没有初始化,但也必须在类外进行定义。由于没有生成CPublic类的实例,所以它的构造函数和析构函数都不会被执行,在里面做什么工作都没有什么意义。

  ③ 如果静态函数需要访问CPublic类内的变量,这些变量也必须为静态的。因为非静态量在不生成实例时都不会存在。 如:

class CPublic
{
public:
int x; //内部变量
static int f(int y) //全局函数
{
x++;
return x;
};
…………
};

  这里x虽为类内成员,但如果不生成CPublic类的实例,就会出现函数f()存在,而变量x不存在的问题。

  总之,用没有实例的类管理全局量是一个不错的选择,它具有集中管理,使用方便的好处。当然,除非特别必要,全局量还是少用为好,一个好的编程者决不会随意滥用全局量的,一个封装做得不好的程序,在修改维护时会让你吃足苦头。