goahead-3.3.6版本源码方式移植到wince

从Linux下的goahead-3.3.6版本移植到wince平台
官网文档表示可以直接支持,但是因为我们wince系统的裁剪
以及我当前开发环境是 visual studio 2005 ,而3.3.6版本需要2010版本后的vs才可以打开
所以直接从源码开始编译移植,并且部分接口在我们系统无法使用 需要重写
先知道需要知道有哪些.c/.cpp文件需要编译,可以通过阅读Linux下gcc编译日志查看

cc -shared -o build/linux-x64-default/bin/libgo.so 
'-rdynamic' 
'-Wl,--enable-new-dtags' 
'-Wl,-rpath,$ORIGIN/' 
-g -Lbuild/linux-x64-default/bin    
"build/linux-x64-default/obj/action.o" 
"build/linux-x64-default/obj/alloc.o" 
"build/linux-x64-default/obj/auth.o" 
"build/linux-x64-default/obj/cgi.o" 
"build/linux-x64-default/obj/crypt.o" 
"build/linux-x64-default/obj/file.o" 
"build/linux-x64-default/obj/fs.o" 
"build/linux-x64-default/obj/http.o" 
"build/linux-x64-default/obj/js.o" 
"build/linux-x64-default/obj/jst.o" 
"build/linux-x64-default/obj/options.o" 
"build/linux-x64-default/obj/osdep.o" 
"build/linux-x64-default/obj/rom-documents.o" 
"build/linux-x64-default/obj/route.o" 
"build/linux-x64-default/obj/runtime.o" 
"build/linux-x64-default/obj/socket.o" 
"build/linux-x64-default/obj/upload.o" 
"build/linux-x64-default/obj/est.o" 
"build/linux-x64-default/obj/matrixssl.o" 
"build/linux-x64-default/obj/nanossl.o" 
"build/linux-x64-default/obj/openssl.o"  
-lest -lest -lrt -ldl -lpthread -lm 

其中删除掉ssl加密相关的接口, 只需要一个比较简单实用有基础功能的webs服务器即可
src/ssl/est.c, src/ssl/matrixssl.c, src/ssl/nanossl.c, src/ssl/openssl.c
加入了获取IP的接口
netconfig.c

就是下面的情况
这里写图片描述

其中源码中需要改动的接口有:
1 文件读写
2 获取文件大小以及文件修改时间
3 获取系统时间以及相关时间转换
4 设置和获取IP地址

1 文件读写

    1>------ 已启动生成: 项目: goahead-3.3.6, 配置: Debug SDK1 (ARMV4I) ------
    1>正在链接...
    1>   正在创建库 SDK1 (ARMV4I)\Debug/goahead-3.3.6.lib 和对象 SDK1 (ARMV4I)\Debug/goahead-3.3.6.exp
    1>libgo.lib(fs.obj) : error LNK2019: 无法解析的外部符号 close,该符号在函数 websCloseFile 中被引用
    1>libgo.lib(upload.obj) : error LNK2001: 无法解析的外部符号 close
    1>libgo.lib(fs.obj) : error LNK2019: 无法解析的外部符号 stat,该符号在函数 websStatFile 中被引用
    1>libgo.lib(cgi.obj) : error LNK2001: 无法解析的外部符号 stat
    1>libgo.lib(fs.obj) : error LNK2019: 无法解析的外部符号 read,该符号在函数 websReadFile 中被引用
    1>libgo.lib(cgi.obj) : error LNK2001: 无法解析的外部符号 read
    1>libgo.lib(fs.obj) : error LNK2019: 无法解析的外部符号 lseek,该符号在函数 websSeekFile 中被引用
    1>libgo.lib(cgi.obj) : error LNK2001: 无法解析的外部符号 lseek
    1>libgo.lib(fs.obj) : error LNK2019: 无法解析的外部符号 write,该符号在函数 websWriteFile 中被引用
    1>libgo.lib(upload.obj) : error LNK2001: 无法解析的外部符号 write
    1>libgo.lib(file.obj) : error LNK2001: 无法解析的外部符号 write
    1>libgo.lib(cgi.obj) : error LNK2001: 无法解析的外部符号 write
    1>libgo.lib(auth.obj) : error LNK2019: 无法解析的外部符号 time,该符号在函数 websOpenAuth 中被引用
    1>libgo.lib(upload.obj) : error LNK2019: 无法解析的外部符号 unlink,该符号在函数 freeUploadFile 中被引用
    1>libgo.lib(file.obj) : error LNK2001: 无法解析的外部符号 unlink
    1>libgo.lib(cgi.obj) : error LNK2001: 无法解析的外部符号 unlink
    1>libgo.lib(upload.obj) : error LNK2019: 无法解析的外部符号 getenv,该符号在函数 websUploadOpen 中被引用
    1>libgo.lib(cgi.obj) : error LNK2019: 无法解析的外部符号 chdir,该符号在函数 cgiHandler 中被引用
    1>libgo.lib(cgi.obj) : error LNK2019: 无法解析的外部符号 getcwd,该符号在函数 cgiHandler 中被引用
    1>libgo.lib(cgi.obj) : error LNK2019: 无法解析的外部符号 CreateProcessA,该符号在函数 launchCgi 中被引用
    1>libgo.lib(socket.obj) : error LNK2001: 无法解析的外部符号 errno
    1>SDK1 (ARMV4I)\Debug/goahead-3.3.6.exe : fatal error LNK1120: 12 个无法解析的外部命令
    1>生成日志保存在“file://e:\goahead.wince\goahead-3.3.6\goahead-3.3.6\SDK1 (ARMV4I)\Debug\BuildLog.htm”
    1>goahead-3.3.6 - 22 个错误,0 个警告
    ========== 生成: 0 已成功, 1 已失败, 0 最新, 0 已跳过 ==========

需要把相关的open/write/read/close 改成 fopen/fwrite/fread/fclose
就需要把文件描述符(int)改成操作文件的指针(FILE*)了
对应的属性替换成FILE*

这里写图片描述
对应的函数替换成fopen/fwrite/fread/fclose等
这里写图片描述
需要把对应的5个实现修改完成

2 获取文件大小以及文件修改时间

time_t SystemTimeToTimet(SYSTEMTIME st){
    FILETIME ft;
    time_t pt;
    LONGLONG nLL;
    ULARGE_INTEGER ui;
    SystemTimeToFileTime( &st, &ft );
    ui.LowPart = ft.dwLowDateTime;
    ui.HighPart = ft.dwHighDateTime;
    nLL = (ft.dwHighDateTime << 32) + ft.dwLowDateTime;
    pt = (long)((LONGLONG)(ui.QuadPart - 116444736000000000) / 10000000);
    return pt;
}

PUBLIC int websStatFile(char *path, WebsFileInfo *sbuf)
{
    WIN32_FILE_ATTRIBUTE_DATA   lpFileInformation;
    wchar_t wFilePath[64] = {L'0'};
    char testPath[128];
    int formatlength = 0;
    int i = 0;
    SYSTEMTIME systime;
    WebsStat    s;
    ssize len = slen(path) - 1;
    strcpy(testPath, path);
    path = sclone(path);
    if (path[len] == '/') {
        path[len] = '\0';
    } else if (path[len] == '\\') {
        path[len - 1] = '\0';
    }
    wfree(path);
    formatlength = strlen(testPath);
    MultiByteToWideChar(CP_ACP,0,testPath,formatlength,wFilePath,formatlength+1);
    GetFileAttributesEx(wFilePath, GetFileExInfoStandard, &lpFileInformation);
    sbuf->size = (lpFileInformation.nFileSizeHigh << 32) | lpFileInformation.nFileSizeLow;
    FileTimeToSystemTime(&lpFileInformation.ftLastWriteTime,&systime);
    sbuf->mtime = SystemTimeToTimet(systime);
    if(GetFileAttributesW(wFilePath)& FILE_ATTRIBUTE_DIRECTORY){
        //dirrect
        sbuf->isDir = 1;
    }else{
        sbuf->isDir = 0;
    }
    return 0;  
}

3 相关时间转换 time_t和SYSTEMTIME的替换函数

time_t GetSystemTimet(){
    SYSTEMTIME st;
    FILETIME ft;
    time_t pt;
    LONGLONG nLL;
    ULARGE_INTEGER ui;
    //struct tm gm;
    GetLocalTime( &st );
    SystemTimeToFileTime( &st, &ft );
    ui.LowPart = ft.dwLowDateTime;
    ui.HighPart = ft.dwHighDateTime;
    nLL = (ft.dwHighDateTime << 32) + ft.dwLowDateTime;
    pt = (long)((LONGLONG)(ui.QuadPart - 116444736000000000) / 10000000);
    return pt;
}

SYSTEMTIME TimetToSystemTime(time_t t){
    FILETIME ft;
    SYSTEMTIME pst;
    LONGLONG nLL = Int32x32To64(t, 10000000) + 116445024000000000;
    ft.dwLowDateTime = (DWORD)nLL;
    ft.dwHighDateTime = (DWORD)(nLL >> 32);
    FileTimeToSystemTime(&ft, &pst);
    return pst;
}

GetLocalTime是一个Windows API 函数,用来获取当地的当前系统日期和时间

#include <iostream>
#include<time.h>

#include<windows.h>
#include<winbase.h>
using namespace std;

int main() {
    SYSTEMTIME ltime;
    GetLocalTime(&ltime);
    printf("the systemtime is:");
    printf("%d/%02d/%02d  %02d:%02d:%02d",ltime.wYear,ltime.wMonth,
        ltime.wDay,ltime.wHour,ltime.wMinute,ltime.wSecond);
    getchar();
    return 0;
}

相对于Windows而言 Linux 没有提供特定的接口获取时间
Linux下一般是通过标C函数,来获取系统时间,当然window下也可以使用

#include <iostream>
#include<time.h>

#include<windows.h>
#include<winbase.h>
using namespace std;

int main() {
    struct tm *t;
    time_t tt;
    time(&tt);
    t=localtime(&tt);
    printf("%d/%02d/%02d  %02d:%02d:%02d\n",t->tm_year+1900,
        t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
    getchar();
    return 0;
}

4 设置和获取IP地址
直接参考 http://blog.csdn.net/dreamintheworld/article/details/77935225

//http.c
static int setLocalHost(){
    struct in_addr  intaddr;
    char            host[128], ipaddr[128];
    wchar_t UsbNetWorkName[32] = L"EMAC1";
    NETWORK_ADPT_INFO tAdapterInfo = {0};
    if (gethostname(host, sizeof(host)) < 0) {
        //error("Cannot get hostname: errno %d", errno);
        return -1;
    }
    struct hostent  *hp;

    if (GetIPAddress((wchar_t*)UsbNetWorkName,&tAdapterInfo)){
        IPAddrToStr(ipaddr,tAdapterInfo.IPAddr);
    }
    websSetIpAddr(ipaddr);
    websSetHost(ipaddr);
    return 0;
}

5 配置文件的换行解析
auth.txt 和 route.txt 文件需要重新整理换行,修改linux下的\n(0x0A)为windows下面的 \r\n(0x0D,0x0A)
这里写图片描述

6 实现asctime
当前开发环境下编译器没有提供到asctime函数, 所以需要重新实现
char* asctime (const struct tm * timeptr).
返回字符串格式为 Wed Feb 13 15:46:11 2013

void format2asctime(char*result, time_t timeT){
    char week[8] = {0};
    char month[8] = {0};
    SYSTEMTIME systime = TimetToSystemTime(timeT);
    switch(systime.wMonth){
        case 0: sprintf(month, "Jan");break;
        case 1: sprintf(month, "Feb");break;
        case 2: sprintf(month, "Mar");break;
        case 3: sprintf(month, "Apr");break;
        case 4: sprintf(month, "May");break;
        case 5: sprintf(month, "Jun");break;
        case 6: sprintf(month, "Jul");break;
        case 7: sprintf(month, "Aug");break;
        case 8: sprintf(month, "Sept");break;
        case 9: sprintf(month, "Oct");break;
        case 10: sprintf(month, "Nov");break;
        case 11: sprintf(month, "Dec");break;
        default: sprintf(month, "Jan");break;
    }
    switch(systime.wDayOfWeek){
        case 0: sprintf(week, "Mon");break;
        case 1: sprintf(week, "Tues");break;
        case 2: sprintf(week, "Wed");break;
        case 3: sprintf(week, "Thur");break;
        case 4: sprintf(week, "Fri");break;
        case 5: sprintf(week, "Sat");break;
        case 6: sprintf(week, "Sun");break;
        default: sprintf(week, "Mon");break;
    }
    sprintf(result, "%s %s %02d %02d:%02d:%02d %d", week, month, systime.wDay,
        systime.wHour, systime.wMinute, systime.wSecond, systime.wYear);
}

7 创建进程函数CreateProcessA
报错: 1>libgo.lib(cgi.obj) : error LNK2019: 无法解析的外部符号 CreateProcessA,该符号在函数 launchCgi 中被引用
直接使用CreateProcess会调用到CreateProcessA, 需要手动修改宏定义为CreateProcessW
#define CreateProcess CreateProcessW//CreateProcessA

运行结果:
这里写图片描述

移植到Linux平台下的方法:
http://blog.csdn.net/dreamintheworld/article/details/75407076

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值