본문 바로가기

C-Language/Pro C, VS2008 Express

Pro C with VS 2008 Express Integration & test

Oracle Pro*C, Visual Studio 2008 Express Edition, Oracle 11g (Oracle 10g)

현재 시스템에 Oracle 11g가 설치된 것으로 간주하고 Pro*C를 Visual Studio 2008 Express Edition과 통합하여 개발환경을 구성하는 절차에 대해서 알아본다.

Download Visual Studio 2008 Express Edition 여기에 접속하여 화면의 중앙에 3개의 탭 중에서 Visual Studio 2008 Express를 선택한다.
설치 : 기본으로 설정된 내용대로 설치한다.

pcscfg.cfg 파일 편집

C:\oracle\11.1.0\db_1\precomp\admin\pcscfg.cfg 파일을 열고 다음과 같이 추가해준다.

pcscfg.cfg

define=(WIN32_LEAN_AND_MEAN)
sys_include=C:\PROGRA~1\MICROS~1.0\VC\include\sys
include=C:\PROGRA~1\MICROS~3\Windows\v6.1\Include
include=C:\PROGRA~1\MICROS~1.0\VC\include

위의 내용 중에서 축약된 폴더명이 보이는데, Pro C에서는 디렉토리 이름에 공백이 포함되어 있으면 오류를 발생하므로 공백을 포함한 폴더명을 축약형으로 입력한 것이다. 원래의 경로명은 다음과 같다.

sys_include=C:\Program Files\Microsoft Visual Studio 9.0\VC\include\sys
include=C:\Program Files\Microsoft SDKs\Windows\v6.1\Include
include=C:\Program Files\Microsoft Visual Studio 9.0\VC\include

공백문자를 포함한 폴더명의 축약형 이름을 구하는 방법은 커맨드라인에서 해당 폴더명이 보이는 상위의 폴더로 이동하여 dir /x 명령을 하면 확인할 수 있다.


VS 2008에 Pro C include 패스 등록
도구 > 옵션 > VC++ 디렉터리 > 포함파일 > 경로추가(폴더아이콘) > ...버튼을 눌러 아래의 경로를 추가한다

C:\product\11.1.0\db_1\precomp\public



VS 2008에 Pro C library 패스 등록
도구 > 옵션 > VC++ 디렉터리 > 라이브러리 파일 > 경로추가(폴더아이콘) > ... 버튼을 눌러 아래의 경로를 추가한다

C:\product\11.1.0\db_1\precomp\LIB
C:\product\11.1.0\db_1\precomp\LIB\msvc



VS 2008에서 새로운 프로젝트 생성 (Win32 Empty Project)

파일 > 새로 만들기 > 프로젝트 > Visual C++ > Win32 > Win32 콘솔 응용 프로그램 >
이름: ProcTest 입력 > 확인 > 콘솔 응용 프로그램 체크, 빈 프로젝트 체크 > 마침

주의: 프로젝트가 저장되는 경로에 공백문자가 포함되면 컴파일과정에서 오류가 발생하므로 프로젝트저장 경로를 변경하여 지정해 주어야 한다.

프로젝트의 소스파일 아래에 proctest.pc 파일을 생성하고 다음과 같이 입력한다.
프로젝트 하위폴더의 소스파일 > 추가 > 새항목 > Visual C++ > C++ 파일 선택, 이름: ProcTest.pc 입력 > 추가

ProcTest.pc

/*
** suppress certain warnings
*/

#ifdef WIN32
#define _CRT_SECURE_NO_DEPRECATE 1
#endif

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sqlca.h>
#include <sqlda.h>
#include <sqlcpr.h>

EXEC SQL BEGIN DECLARE SECTION;

/*
** defines for VARCHAR lengths.
*/

#define UNAME_LEN 30
#define PWD_LEN   30
#define DB_LEN    48
#define ENAME_LEN 32
#define JOB_LEN 32

/*
** variables for the connection
*/

char *username = "scott";
char *password = "ojtit";
char *dbname = "orcl";
char * connstr = "scott/ojtit@orcl";
/*
** variables to hold the results
* VARCHAR 형으로 선언하면 Pre-Compiler에 의해 구조체로 변환되어 arr, len속성을 갖는다
* arr속성은 문자열을 저장하는 배열이고, len은 arr 배열에 동적으로 할당된 크기가 정수로 저장
*/

int ctr;
int empno;
VARCHAR ename[ENAME_LEN];
VARCHAR job[JOB_LEN];

EXEC SQL END DECLARE SECTION;

/*
** declare error handling function
*/

void sql_error(char *msg)
{
  char err_msg[128];
  size_t buf_len, msg_len;

  EXEC SQL WHENEVER SQLERROR CONTINUE;

  printf("\n%s\n", msg);
  buf_len = sizeof (err_msg);
  sqlglm(err_msg, &buf_len, &msg_len);
  printf("%.*s\n", msg_len, err_msg);

  EXEC SQL ROLLBACK RELEASE;

  exit(EXIT_FAILURE);
}

int main(void)
{
  /*
  ** register sql_error() as the error handler.
  */

  EXEC SQL WHENEVER SQLERROR DO sql_error("ORACLE error--\n");

  /*
  ** Connect to database.  Will call sql_error()
  ** if an error occurs when connecting.
  */

  EXEC SQL CONNECT :username IDENTIFIED BY :password USING :dbname;
  // 위의 문장대신에 우측처럼 해도 됨 --> EXEC SQL CONNECT :connstr;

  printf("\nConnected to ORACLE as user: %s\n\n", username);

  /*
  ** simple select statement
  */

  EXEC SQL DECLARE emps CURSOR FOR
    SELECT   empno,
             ename,
             job
    FROM     emp
    ORDER BY ename,
             empno;
  /*
  ** open the cursor
  */

  EXEC SQL OPEN emps;

  /*
  ** when done fetching break out of the for loop
  */

  EXEC SQL WHENEVER NOT FOUND DO break;

  /*
  ** simple counter variable
  */

  ctr = 0;

  /*
  ** print a little header
  */

  printf(" EMPNO         ENAME                JOB\n");
  printf("===========  ==============  =========================\n");

  /*
  ** fetch all the rows
  */

  for (;;)
  {
    EXEC SQL FETCH emps into :empno, :ename, :job;

    /*
    ** null-terminate the string values
    */

    ename.arr[ename.len] = '\0';
    job.arr[job.len] = '\0';

    /*
    ** print the current values
    */

    printf("%-15d%-22s%-25s\n", empno, ename.arr, job.arr);

    ctr++;
  }

  /*
  ** close the cursor
  */

  EXEC SQL CLOSE emps;

  /*
  ** provide simple feedback on how many rows fetched
  */

  printf("\nFetched %d employees.\n", ctr);

  /*
  ** disconnect from database
  */

  EXEC SQL ROLLBACK WORK RELEASE;

  /*
  ** have a nice day
  */

  exit(EXIT_SUCCESS);
}



ProcTest.pc 파일이 참조할 ProcTest.c 파일 생성(내용이 없는 파일)

프로젝트 하위폴더의 소스파일 > 추가 > 새항목 > Visual C++ > C++ 파일 선택, 이름: ProcTest.c 입력 > 추가


프로젝트에 Pro C 라이브러리(orasql11.lib)추가
프로젝트 위에서 마우스 우측 > 속성 > 구성속성 > 링커 > 입력 > 추가 종속성: orasql11.lib입력 > 적용 > 확인


Custom Build Step

Visual Studio가 Pro*C (proc.exe)를 실행하여 *.c 소스를 생성할 수 있도록 커맨드라인과 출력파일 이름을 설정한다.
소스파일 > ProcTest.pc 위에서 마우스 우측 > 속성 > 사용자 지정 빌드 단계 >
명령줄: proc.exe $(ProjectDir)$(InputName).pc
출력 : $(ProjectDir)$(InputName).c
적용 > 확인

*.pc 파일을 컴파일하여 *.c 파일 생성

소스파일 > ProcTest.pc 위에서 마우스우측 > 컴파일
위의 명령으로 다음과 같은 출력 메시지를 확인할 수 있다.

1>------ 빌드 시작: 프로젝트: ProcTest, 구성: Debug Win32 ------
1>사용자 지정 빌드 단계 수행 중
1>Pro*C/C++: Release 10.2.0.1.0 - Production on 금 8월 27 22:21:02 2010
1>Copyright (c) 1982, 2005, Oracle.  All rights reserved.
1>시스템 기본 옵션 값이 가지고 온 곳: E:\oracle\product\10.2.0\db_1\precomp\admin\pcscfg.cfg
1>빌드 로그가 "file://e:\C_Test\ProcTest\ProcTest\Debug\BuildLog.htm"에 저장되었습니다.
1>ProcTest - 오류: 0개, 경고: 0개
========== 빌드: 성공 1, 실패 0, 최신 0, 생략 0 ==========

 

Build the Sample and Verify

이제 *.pc 파일은 성공적으로 *.c 파일을 생성하였으므로 *.c 소스를 빌드하여 실행파일을 생성할 순서이다.
빌드 > 솔루션 빌드
위의 명령은 다음과 같은 메시지를 출력한다.

1>------ 빌드 시작: 프로젝트: ProcTest, 구성: Debug Win32 ------
1>컴파일하고 있습니다...
1>ProcTest.c
1>링크하고 있습니다...
1>매니페스트를 포함하고 있습니다...
1>빌드 로그가 "file://e:\C_Test\ProcTest\ProcTest\Debug\BuildLog.htm"에 저장되었습니다.
1>ProcTest - 오류: 0개, 경고: 0개
========== 빌드: 성공 1, 실패 0, 최신 0, 생략 0 ==========



프로그램 실행

디버그 > 디버깅하지 않고 시작

프로그램을 실행하면 다음과 같이 오라클에서 가져온 데이터가 출력된다.

Connected to ORACLE as user: scott

 EMPNO         ENAME                JOB
===========  ==============  =========================
7876         ADAMS                 CLERK
7499         ALLEN                 SALESMAN
7698         BLAKE                 MANAGER
7782         CLARK                 MANAGER
7902         FORD                  ANALYST
7900         JAMES                 CLERK
7566         JONES                 MANAGER
7839         KING                  PRESIDENT
7654         MARTIN                SALESMAN
7934         MILLER                CLERK
7788         SCOTT                 ANALYST
7369         SMITH                 CLERK
7844         TURNER                SALESMAN
7521         WARD                  SALESMAN

Fetched 14 employees.
계속하려면 아무 키나 누르십시오 . . .