WinCE应用程序开发接口通Windows相同,主要分为分为MFC、ALT、C/C++ run-time library、Win32等4类。
WinCE Application Frameworks 也包括了MFC 和ATL,它们主要用来支持使用Microsoft Visual C++ 语言开发WinCE 的应用程序,二者皆提供了应用接口层在Windows 平台的可移植性。
WinCE提供了符合Windows 平台标准的开发环境,它是Win32 API 的一个子集,涵盖了大部分的Win32 功能。
C run-time library又分为动态运行时库和静态运行时库。动态运行时库主要是DLL库文件msvcrt.dll,对应的Import library文件是msvcrt..lib;静态运行时库对应的主要文件是:libc.lib (Single thread),libc.lib(Multithread)。
Standard C++ Library包括C run-time library 和 STL。VC提供的Standard C++ Library主要包括:libcp.lib,libcpmt.lib和msvcprt.lib。
WinCE与Windows相比,提供的C run-time library支持较少,也带来了部分程序移植上的困难。下面将Windows和WinCE的C run-time library支持的API进行对比,会发现WinCE只支持少量API。(通过VC6自带的depends工具获取)
Windows的Crun-time library支持的API
WinCE的Crun-time library支持的API
最近,我移植UPnP CyberLink库(C++)到WinCE遇到了一些问题和解决方法如下:
1. WinCE编译时不支持stat函数,无sys/stat.h文件
解决方法: 用WinCE的Win32接口代替stat函数实现类成员函数。可参考微软的代码和MSDN。
实现代码如下:
#ifndef WINCE
#include <sys/stat.h>
#endif
long File::lastModified()
{
#ifndef WINCE
structstat buf ;
if(stat(getName(),&buf) == -1)
return0;
returnbuf.st_mtime;
#else
#defineEPOCH_BIAS 116444736000000000i64
WIN32_FIND_DATAfd;
ZeroMemory(&fd,sizeof(WIN32_FIND_DATA));
constchar * name = getName();
wchar_tdest[_MAX_PATH];
int i = mbstowcs(dest, name, _MAX_PATH);
HANDLEhFind = FindFirstFile(dest, &fd);
if(hFind == INVALID_HANDLE_VALUE)
return0;
__int64t = fd.ftLastWriteTime.dwHighDateTime;
t<<= 32;
t|= fd.ftLastWriteTime.dwLowDateTime;
t-= EPOCH_BIAS;
FindClose(hFind);
return (t / 10000000i64);
#endif
}
long File::length()
{
#ifndef WINCE
structstat buf ;
if(stat(getName(),&buf ) == -1)
return0;
returnbuf.st_size;
#else
WIN32_FIND_DATAfd;
ZeroMemory(&fd,sizeof(WIN32_FIND_DATA));
constchar * name = getName();
wchar_tdest[_MAX_PATH];
int i = mbstowcs(dest, name, _MAX_PATH);
HANDLEhFind = FindFirstFile(dest, &fd);
if(hFind == INVALID_HANDLE_VALUE)
return0;
DWORDLONG FileSize = (fd.nFileSizeHigh * (MAXDWORD+1)) +fd.nFileSizeLow;
printf ("The first file %s,size is %ld bytes\n", fd.cFileName, FileSize);
FindClose(hFind);
return FileSize;
#endif
}
bool File::isDirectory()
{
#ifndef WINCE
structstat buf ;
if(stat(getName(),&buf) == -1)
returnfalse;
#else
WIN32_FIND_DATAfd;
ZeroMemory(&fd,sizeof(WIN32_FIND_DATA));
constchar * name = getName();
wchar_tdest[_MAX_PATH];
int i = mbstowcs(dest, name, _MAX_PATH);
HANDLEhFind = FindFirstFile(dest, &fd);
if(hFind == INVALID_HANDLE_VALUE)
returnfalse;
boolret = ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ==FILE_ATTRIBUTE_DIRECTORY);
FindClose(hFind);
returnret;
#endif
}
bool File::isFile()
{
#ifndef WINCE
structstat buf ;
if(stat(getName(),&buf) == -1)
returnfalse;
return ((buf.st_mode &_S_IFMT)==_S_IFREG) ? true : false;
#else
WIN32_FIND_DATAfd;
ZeroMemory(&fd,sizeof(WIN32_FIND_DATA));
constchar * name = getName();
wchar_tdest[_MAX_PATH];
int i = mbstowcs(dest, name, _MAX_PATH);
HANDLEhFind = FindFirstFile(dest, &fd);
if(hFind == INVALID_HANDLE_VALUE)
returnfalse;
boolret = !((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ==FILE_ATTRIBUTE_DIRECTORY);
FindClose(hFind);
returnret;
#endif
}
2. WinCE中链接time, mktime,gmtime, localtime这几个时间相关函数会报错。
_CRTIMP __time64_t __cdecl _mktime64(structtm *);
_CRTIMP __time64_t __cdecl _time64(__time64_t *);
_CRTIMP errno_t __cdecl_gmtime64_s(struct tm *ptm, const __time64_t *);
_CRTIMP errno_t __cdecl_localtime64_s(struct tm *ptm, const __time64_t *);
解决方法: 自定义上述函数。
l 参考微软的代码实现
MicrosoftVisual Studio 8\VC\ce\include\altcecrt.h
MicrosoftVisual Studio 8\VC\ce\crt\src目录中time64.c,mktime64.c, gmtime64.c, localtime64.c。
l 网络查找参考源码
http://www.sapphire-lang.org/repositories/browse/sapphire/WinCE
实现代码如下:
#ifdef WINCE
#include <windows.h>
#define EPOCH_BIAS 116444736000000000i64
const __int64 _onesec_in100ns =(__int64)10000000;
/* __int64 <--> FILETIME */
static __int64wce_FILETIME2int64(FILETIME f)
{
__int64t;
t= f.dwHighDateTime;
t<<= 32;
t|= f.dwLowDateTime;
returnt;
}
static FILETIMEwce_int642FILETIME(__int64 t)
{
FILETIMEf;
f.dwHighDateTime= (DWORD)((t >> 32) & 0x00000000FFFFFFFF);
f.dwLowDateTime = (DWORD)( t & 0x00000000FFFFFFFF);
returnf;
}
/* FILETIME utility */
static FILETIMEwce_getFILETIMEFromYear(WORD year)
{
SYSTEMTIMEs={0};
FILETIMEf;
s.wYear = year;
s.wMonth = 1;
s.wDayOfWeek= 1;
s.wDay = 1;
SystemTimeToFileTime(&s, &f );
returnf;
}
static time_t wce_getYdayFromSYSTEMTIME(constSYSTEMTIME* s)
{
__int64t;
FILETIMEf1, f2;
f1= wce_getFILETIMEFromYear( s->wYear );
SystemTimeToFileTime(s, &f2 );
t= wce_FILETIME2int64(f2)-wce_FILETIME2int64(f1);
return(time_t)((t/_onesec_in100ns)/(60*60*24));
}
/* tm <--> SYSTEMTIME */
static SYSTEMTIMEwce_tm2SYSTEMTIME(struct tm *t)
{
SYSTEMTIMEs;
s.wYear = t->tm_year + 1900;
s.wMonth = t->tm_mon + 1;
s.wDayOfWeek= t->tm_wday;
s.wDay = t->tm_mday;
s.wHour = t->tm_hour;
s.wMinute = t->tm_min;
s.wSecond = t->tm_sec;
s.wMilliseconds= 0;
returns;
}
static struct tmwce_SYSTEMTIME2tm(SYSTEMTIME *s)
{
structtm t;
t.tm_year = s->wYear - 1900;
t.tm_mon = s->wMonth- 1;
t.tm_wday = s->wDayOfWeek;
t.tm_mday = s->wDay;
t.tm_yday = wce_getYdayFromSYSTEMTIME(s);
t.tm_hour = s->wHour;
t.tm_min = s->wMinute;
t.tm_sec = s->wSecond;
t.tm_isdst= 0;
returnt;
}
/* FILETIME <--> time_t */
time_t wce_FILETIME2time_t(constFILETIME* f)
{
__int64t = wce_FILETIME2int64(*f) - EPOCH_BIAS;
return(time_t)(t / _onesec_in100ns);
}
FILETIME wce_time_t2FILETIME(consttime_t t)
{
FILETIMEf, f1970;
__int64time;
f1970= wce_getFILETIMEFromYear(1970);
time= t;
time*= _onesec_in100ns;
time+= wce_FILETIME2int64(f1970);
f= wce_int642FILETIME(time);
returnf;
}
/* time.h difinition */
time_t time( time_t *timer )
{
SYSTEMTIMEs;
FILETIME f;
if(timer==NULL ) return 0;
GetSystemTime(&s );
SystemTimeToFileTime(&s, &f );
//printf("time is %ld, %ld\n", f.dwHighDateTime, f.dwLowDateTime);
*timer= wce_FILETIME2time_t(&f);
return*timer;
}
struct tm *localtime( const time_t*timer )
{
SYSTEMTIMEss, ls, s;
FILETIME sf, lf, f;
__int64t, diff;
staticstruct tm tms;
GetSystemTime(&ss);
GetLocalTime(&ls);
SystemTimeToFileTime(&ss, &sf );
SystemTimeToFileTime(&ls, &lf );
diff= wce_FILETIME2int64(sf) - wce_FILETIME2int64(lf);
f= wce_time_t2FILETIME(*timer);
t= wce_FILETIME2int64(f) - diff;
f= wce_int642FILETIME(t);
FileTimeToSystemTime(&f, &s );
tms= wce_SYSTEMTIME2tm(&s);
return&tms;
}
time_t mktime(struct tm* pt)
{
SYSTEMTIMEss, ls, s;
FILETIME sf, lf, f;
__int64diff;
GetSystemTime(&ss);
GetLocalTime(&ls);
SystemTimeToFileTime(&ss, &sf );
SystemTimeToFileTime(&ls, &lf );
diff= (wce_FILETIME2int64(lf)-wce_FILETIME2int64(sf))/_onesec_in100ns;
s= wce_tm2SYSTEMTIME(pt);
SystemTimeToFileTime(&s, &f );
returnwce_FILETIME2time_t(&f) - (time_t)diff;
}
struct tm *gmtime(const time_t *t)
{
FILETIMEf;
SYSTEMTIMEs;
staticstruct tm tms;
f= wce_time_t2FILETIME(*t);
FileTimeToSystemTime(&f,&s);
tms= wce_SYSTEMTIME2tm(&s);
return&tms;
}
#endif
3. 在WinCE中编译时不支持itoa函数
解决办法:用_itoa函数代替itoa函数。
实现代码:
#ifdef WINCE
#define itoa _itoa
#endif