用Cygwin模擬DB2的Unix/Linux開(kāi)發(fā)環(huán)境(2)
2024-09-06 23:58:01
供稿:網(wǎng)友
執(zhí)行初始化了db2環(huán)境的cygwin 點(diǎn)擊桌面上的cygwin圖標(biāo),可以進(jìn)入cygwin模擬的linux.. 現(xiàn)在,該環(huán)境不能執(zhí)行db2命令,因?yàn)闆](méi)有作db2cmd初始化環(huán)境。 為了能在該環(huán)境中使用db2,必須先運(yùn)行db2cmd然后在db2的命令行環(huán)境下進(jìn)入cygwin測(cè)試,是否能在cygwin環(huán)境下使用db2命令。ok,到目前為止,我們已經(jīng)擁有了一個(gè)和unix一樣的環(huán)境,并且能使用db2下一步我們來(lái)寫(xiě)第一個(gè)sqc程序. 編寫(xiě)sqc程序 編寫(xiě)一個(gè)簡(jiǎn)單程序測(cè)試,該程序主要完成,讀取系統(tǒng)時(shí)間,并打印。程序主要部分為: if (connectdatabase(sdbname,susername,spasswd)<0) /*連接數(shù)據(jù)庫(kù)*/ { printf("連接數(shù)據(jù)庫(kù)失敗/n"); return -1; } printf("連接數(shù)據(jù)庫(kù)成功!/n"); exec sql select char(current timestamp) into :sdatetime from (values 1) as a; if dataerror { disconnectdb(); return -1; } printf("當(dāng)前時(shí)間%s/n",sdatetime); disconnectdb(); (完整程序建附件)該程序在unix主機(jī)下能編譯執(zhí)行。前面說(shuō)過(guò),建立這個(gè)環(huán)境的主要意義在于方便代碼移植。所以,代碼本身不用作任何更改即可在cygwin環(huán)境下編譯。修改編譯參數(shù) 安裝過(guò)程中已經(jīng)說(shuō)明cygwin環(huán)境下,支持大部分unix/linux命令并且安裝了gcc的編譯器,windows平臺(tái)和unix平臺(tái)下的庫(kù)略有不同,gcc和我們?cè)趙indows下常用的vc編譯器參數(shù)也略有不同,下面簡(jiǎn)要說(shuō)明。1、 在unix環(huán)境中,分為靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù),它們的擴(kuò)展名分別是 .a 和 .so .2、 在windows中,靜態(tài)庫(kù)擴(kuò)展名為 .lib 動(dòng)態(tài)庫(kù)擴(kuò)展名為 .dll3、 unix下,sqc程序編譯時(shí)必須鏈接 libdb2.so庫(kù),也就是加上 -ldb2參數(shù)(忽略lib和擴(kuò)展名,這是unix下c編譯器特點(diǎn))4、 windows下,sqc程序必須鏈接db2api.lib靜態(tài)庫(kù)。雖然有上述不同,但是我們的修改卻非常少,本例中使用了以前我為編譯sqc寫(xiě)的makefile模板。在makefile中真正需要修改的只有一行將libs= -l$(db2path)/lib -l$(db2path)/lib/db2修改為libs= -l $(db2path)/lib $(db2path)/lib/db2api.lib當(dāng)然,你還需要更具環(huán)境的不同,修改makefile的其他部分,比如db2path的值啊,這些就是在不同的主機(jī)上也需要修改的,并不是windows和unix的區(qū)別,不在本文的討論之列。 運(yùn)行測(cè)試程序cygwin使用windows文件系統(tǒng),進(jìn)入cygwin環(huán)境后 系統(tǒng)的根目錄/其實(shí)就是你的cygwin安裝目錄。用戶目錄通常在/home/user,(user是你windows的用戶名) 比如在windows環(huán)境中我的cygwin安裝在d:/cygwin 我的用戶目錄是 d:/cygwin/home/rocfu,,如果你在cygwin中使用pwd命令察看當(dāng)前路徑,會(huì)顯示/home/roc. 在用戶目錄下新建db2test子目錄,附件附帶文件 makefile test.sqc,將這三個(gè)文件復(fù)制到db2test目錄.修改 test.sqc中的下面代碼 strcpy(susername,"db2admin"); strcpy(spasswd,"db2admin"); strcpy(sdbname,"dwctrldb");為你自己的服務(wù)器連接(為簡(jiǎn)化測(cè)試程序,這里并沒(méi)有從配置文件中讀取連接信息)執(zhí)行命令 make all你會(huì)發(fā)現(xiàn)編譯的結(jié)果竟然是一個(gè)exe文件,對(duì)了,這是在windows下編譯的程序,當(dāng)然是一個(gè)exe文件了。ok 執(zhí)行該程序,運(yùn)行結(jié)果如下圖總結(jié) 完成上述步驟之后,我們有了一個(gè)仿真的unix環(huán)境,能通過(guò)makefile中的小小改動(dòng),將源代碼在各種平臺(tái)上編譯,當(dāng)你不能連上主機(jī)工作時(shí),完全可以用這個(gè)小巧的環(huán)境暫時(shí)代用。這個(gè)環(huán)境具有unix/linux高級(jí)特性,對(duì)于信號(hào)、管道、多進(jìn)程、守護(hù)進(jìn)程完全支持。 還有更重要的,如果希望這個(gè)程序在windows下脫離cygwin環(huán)境運(yùn)行,只要把cygwin1.dll復(fù)制到windows的system32目錄下即可,這樣,你得程序在一套源碼的情況下,支持兩個(gè)環(huán)境,何樂(lè)而不為。事實(shí)上,很多從linux移植到windows的程序就是這么干的。 附件makefile.suffixes: .sqc .c .o gcc=gcccc=gcc embprep=embprep ccflags=-g -mno-cygwin cflags= $(extra_cflags) -i$(db2path)/include -mno-cygwin db2path=/cygdrive/d/db2/sqllib#libs= -l$(db2path)/lib -l$(db2path)/lib/db2 libs= -l $(db2path)/lib $(db2path)/lib/db2api.lib uid=db2adminpwd=db2admindb=dwctrldb billhome=.billbin=.billsrc=$(billhome)billobj=$(billhome)billlib=../lib include=-i. -i$(billhome)/src -i$(billlib) / -i$(db2path)/include / -i/usr/lib -i/usr/local/include / -i/usr/include target1 = $(billbin)/test all:$(target1) .sqc.o: db2 connect to $(db) user $(uid) using $(pwd);/ db2 prep $*.sqc bindfile;/ db2 bind $*.bnd;/ db2 connect reset;/ db2 terminate;/ $(cc) $(include) -o $*.o -c $(ccflags) $(cflags) $(defs) $*.c ; .c.o: $(cc) $ (include) -o $*.o -c $(ccflags) $(cflags) $(libs) $(defs) $*.c --def tandard.def pick_objs1= $(billsrc)/test.o $(billbin)/test: $(comm_objs) $(pick_objs1) $(cc) $(cflags) -o $(target1) $(pick_objs1) $(comm_objs) $(oracle_lib)$(linkflag) $(libs) clean: rm -f *.o $(target1) test.c test.o test.bnd test.sqc/********************************************************************************** 文件名:test.sqc 創(chuàng)建人: roc.fu 日期 2004-03-07 版 本:v1.0 功 能:讀取系統(tǒng)當(dāng)前時(shí)間 描 述:**********************************************************************************/#include <stdio.h>#include <sql.h>#include <sqlenv.h>#include <sqlda.h>#include <sqlca.h>#include <sqladef.h>#include <sqlenv.h> struct sqlca sqlca;char gusername[20];char gpassword[20];char gservername[20];char gtpassword[20]; #ifndef dataerror#define dataerror (sqlca.sqlcode<0 )#endif /************************************************************************************ 功能 :連接數(shù)據(jù)庫(kù) * 返回值 :0 正常連接 -1 連接失敗* 參數(shù): sdbalias 數(shù)據(jù)庫(kù)名* suser 用戶名* spasswd 密碼***********************************************************************************/int connectdatabase (char *sdbalias,char *suser,char *spasswd){ int rc = 0; char smsg[1024]; exec sql begin declare section ; char db[15] ; char userid[15] ; char passwd[15] ; exec sql end declare section; memset(smsg,0,1024); printf("1/n"); strcpy( db, sdbalias) ; strcpy( userid, suser) ; strcpy( passwd, spasswd) ; if ( strlen(userid) == 0) { printf("2/n"); exec sql connect to :db; } else { printf("用戶名:%s/n",userid); printf("密碼:%s/n",passwd); printf("密碼:%s/n",db); exec sql connect to :db user :userid using :passwd; printf("4/n"); } return 0; } /************************************************************************************ 斷開(kāi)數(shù)據(jù)庫(kù)連接************************************************************************************/void disconnectdb(){ exec sql connect reset;} int main(int argc, char *argv[]) { int iret; exec sql begin declare section; char susername[100]; char spasswd[100]; char sdbname[100]; char sdatetime[100]; exec sql end declare section; printf("start read config.../n"); strcpy(susername,"db2admin"); strcpy(spasswd,"db2admin"); strcpy(sdbname,"dwctrldb"); if (connectdatabase(sdbname,susername,spasswd)<0) /*連接數(shù)據(jù)庫(kù)*/ { printf("連接數(shù)據(jù)庫(kù)失敗/n"); return -1; } printf("連接數(shù)據(jù)庫(kù)成功!/n"); exec sql select char(current timestamp) into :sdatetime from (values 1) as a; if dataerror { disconnectdb(); return -1; } printf("當(dāng)前時(shí)間%s/n",sdatetime); disconnectdb(); printf("完成/n"); return 0;}