CSDN博客

img Roc_fu

用Cygwin模拟DB2的Unix/Linux开发环境(2)

发表于2004/3/12 11:57:00  1246人阅读

执行初始化了DB2环境的Cygwin

  点击桌面上的cygwin图标,可以进入Cygwin模拟的Linux..
  
现在,该环境不能执行DB2命令,因为没有作db2cmd初始化环境。
    
为了能在该环境中使用DB2,必须先运行db2cmd
然后在DB2的命令行环境下进入Cygwin
测试,是否能在Cygwin环境下使用DB2命令。
OK,到目前为止,我们已经拥有了一个和Unix一样的环境,并且能使用DB2
下一步我们来写第一个SQC程序.
 

编写SQC程序

   编写一个简单程序测试,该程序主要完成,读取系统时间,并打印。
程序主要部分为:
      
    if (ConnectDatabase(sDBName,sUserName,sPasswd)<0)   /*连接数据库*/
      {
             printf("连接数据库失败/n");
             return -1;
      }
      printf("连接数据库成功!/n");                           
                    
       EXEC SQL SELECT char(CURRENT TIMESTAMP)
              into :sDateTime
              FROM (VALUES 1) AS A;
      
       if DataError
       {
              DisConnectDB();
              return -1;
       }
       printf("当前时间%s/n",sDateTime);
       DisConnectDB();
 
(完整程序建附件)
该程序在Unix主机下能编译执行。
前面说过,建立这个环境的主要意义在于方便代码移植。所以,代码本身不用作任何更改即可在Cygwin环境下编译。

修改编译参数

       安装过程中已经说明Cygwin环境下,支持大部分Unix/Linux命令并且安装了Gcc的编译器,Windows平台和Unix平台下的库略有不同,gcc和我们在Windows下常用的VC编译器参数也略有不同,下面简要说明。
1、  在Unix环境中,分为静态库和动态库,它们的扩展名分别是 .a 和 .so .
2、  在Windows中,静态库扩展名为 .lib 动态库扩展名为 .dll
3、  Unix下,SQC程序编译时必须链接 libdb2.so库,也就是加上 -ldb2参数(忽略lib和扩展名,这是Unix下C编译器特点)
4、  Windows下,SQC程序必须链接db2api.lib静态库。
虽然有上述不同,但是我们的修改却非常少,本例中使用了以前我为编译SQC写的Makefile模板。在Makefile中真正需要修改的只有一行
LIBS= -L$(DB2PATH)/lib -l$(DB2PATH)/lib/db2
修改为
LIBS= -L $(DB2PATH)/lib $(DB2PATH)/lib/db2api.lib
当然,你还需要更具环境的不同,修改Makefile的其他部分,比如DB2PATH的值啊,这些就是在不同的主机上也需要修改的,并不是Windows和Unix的区别,不在本文的讨论之列。
 

运行测试程序

Cygwin使用Windows文件系统,进入Cygwin环境后 系统的根目录/其实就是你的Cygwin安装目录。用户目录通常在/home/user,(user是你Windows的用户名) 
比如在Windows环境中我的Cygwin安装在d:/Cygwin 我的用户目录是 d:/cygwin/home/rocfu,,如果你在Cygwin中使用pwd命令察看当前路径,会显示/home/roc.
 
在用户目录下新建db2test子目录,附件附带文件 Makefile  test.sqc,将这三个文件复制到db2test目录.
修改 test.sqc中的下面代码
       strcpy(sUserName,"db2admin");
      strcpy(sPasswd,"db2admin");
      strcpy(sDBName,"DWCTRLDB");
为你自己的服务器连接(为简化测试程序,这里并没有从配置文件中读取连接信息)
执行命令 make all
你会发现编译的结果竟然是一个EXE文件,对了,这是在Windows下编译的程序,当然是一个EXE文件了。
OK 执行该程序,运行结果如下图
       完成上述步骤之后,我们有了一个仿真的Unix环境,能通过Makefile中的小小改动,将源代码在各种平台上编译,当你不能连上主机工作时,完全可以用这个小巧的环境暂时代用。这个环境具有Unix/Linux高级特性,对于信号、管道、多进程、守护进程完全支持。
    还有更重要的,如果希望这个程序在Windows下脱离Cygwin环境运行,只要把cygwin1.dll复制到Windows的System32目录下即可,这样,你得程序在一套源码的情况下,支持两个环境,何乐而不为。事实上,很多从Linux移植到Windows的程序就是这么干的。

附件

Makefile

.SUFFIXES: .sqc .c .o
 
GCC=gcc
CC=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=db2admin
PWD=db2admin
DB=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 /standard.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    创建人: Roc.Fu   日期  2004-03-07
 版 本:V1.0       
 功 能:读取系统当前时间                                           
 描 述:
**********************************************************************************/
#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
 
 
 
/**********************************************************************************
*
*     功能 :连接数据库  
*        返回值 :0 正常连接  -1 连接失败
*        参数: sDbAlias 数据库名
*              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;
 
}
 
/***********************************************************************************
*                   断开数据库连接
************************************************************************************/
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)   /*连接数据库*/
      {
             printf("连接数据库失败/n");
             return -1;
      }
      printf("连接数据库成功!/n");                           
                    
       EXEC SQL SELECT char(CURRENT TIMESTAMP)
              into :sDateTime
              FROM (VALUES 1) AS A;
      
       if DataError
       {
              DisConnectDB();
              return -1;
       }
       printf("当前时间%s/n",sDateTime);
       DisConnectDB();
       printf("完成/n");
       return 0;
}
 
0 0

相关博文

我的热门文章

img
取 消
img