제2장 Visual Basic 인터페이스

내용 목차

2.1. 개요
2.2. 함수
2.2.1. FdlErrorMsg
2.2.2. FilltpstartBuf
2.2.3. GETCAR
2.2.4. GETCAR_BA
2.2.5. GETCHR
2.2.6. GETDOUBLE
2.2.7. GETFLOAT
2.2.8. GETINT
2.2.9. GETLONG
2.2.10. GETSTR
2.2.11. GETVAR
2.2.12. PUTCAR
2.2.13. PUTCAR_BA
2.2.14. PUTCHR
2.2.15. PUTDOUBLE
2.2.16. PUTFLOAT
2.2.17. PUTINT
2.2.18. PUTLONG
2.2.19. PUTSTR
2.2.20. PUTVAR
2.2.21. TmaxError
2.3. 예제 프로그램
2.3.1. 프로그램 구성
2.3.2. 프로그램 특징
2.3.3. 공통 프로그램
2.3.4. 클라이언트 프로그램
2.3.5. 서버 프로그램

본 장은 Visual Basic 인터페이스에서 사용하는 함수와 예제를 설명한다.

2.1. 개요

Visual Basic 인터페이스에는 Power Builder와 달리 별도의 모듈이 존재하지 않으며 단순히 클라이언트 라이브러리를 호출할 수 있도록 함수의 프로토타입을 정의한 인터페이스 모듈이 존재한다.

Visual Basic 인터페이스 모듈은 다음과 같다.

모듈설명
atmi.basatmi 함수에 대한 프로토타입 정의 파일이다.
fdl. Bas필드키 함수에 대한 프로토타입 정의 파일이다.
comm.bas사용자의 편리를 위한 매크로 정의 파일이다.
winapi.basWindows에서 제공하는 함수 정의 파일이다.

개발자는 위의 인터페이스 모듈을 설치하면 Tmax 클라이언트 라이브러리에서 제공하는 함수를 호출하여 사용할 수 있다. 하지만 Visual Basic은 값 전달 방법이 기존의 다른 애플리케이션과 많이 다르기 때문에 이 점에 주의하여 사용해야 한다. 또한 직접적인 버퍼 조작이 어렵기 때문에 매크로(comm.bas)를 제공하여 데이터를 입력하고 꺼내는 작업을 내부적으로 처리해준다.

다음은 매크로에서 제공하는 함수의 목록이다.

함수설명
FdlErrorMsg주어진 StrErr 메시지와 함께 fberrno를 화면에 MsgBox로 출력하는 함수이다.
FilltpstartBufTmax 시스템과 연결하기 위해 설정해야 하는 버퍼인 tpstart_t 구조체를 구성하는 함수이다.
GETCARCARRAY 버퍼에 String 데이터 text를 입력하는 함수이다.
GETCAR_BAFIELD(FDL) 버퍼에 Field에 지정된 필드명으로 입력된 필드 순번 idx의 Image 데이터를 ByteArray에 저장하는 함수이다.
GETCHRTmax FDL 함수인 fbchg_tu()를 이용하여 지정한 nth에 해당하는 순번으로 Field에 지정된 필드명에 value값을 가져오는 함수이다.
GETDOUBLEFIELD(FDL) 버퍼에 Field에 지정된 필드명으로 입력된 필드 순번 idx의 Double 데이터를 dData에 저장하는 함수이다.
GETFLOATFIELD(FDL) 버퍼에 Field에 지정된 필드명으로 입력된 필드 순번 idx의 Single 데이터를 dData에 저장하는 함수이다.
GETINTFIELD(FDL) 버퍼에 Field에 지정된 필드명으로 입력된 필드 순번 idx의 Integer 데이터를 iData에 저장하는 함수이다.
GETLONGFIELD(FDL) 버퍼에 Field에 지정된 필드명으로 입력된 필드 순번 idx의 Long 데이터를 lData에 저장하는 함수이다.
GETSTRSTRING 버퍼의 데이터를 text에 저장하는 함수이다.
GETVARFIELD(FDL) 버퍼에 Field에 지정된 필드명으로 입력된 필드 순번 idx의 String 데이터를 text에 저장하는 함수이다.
PUTCARCARRAY 버퍼에 String 데이터 text를 입력하는 함수이다.
PUTCAR_BAFIELD 버퍼에 Image 데이터를 필드 순번으로 입력하는 함수이다.
PUTCHRTmax FDL 함수인 fbchg_tu()를 이용하여 지정한 nth에 해당하는 순번으로 fldName에 지정된 필드명에 value값을 저장하는 함수이다.
PUTDOUBLEFIELD 버퍼에 Double 데이터를 필드 순번으로 입력하는 함수이다.
PUTFLOATFIELD 버퍼에 Single 데이터를 필드 순번으로 입력하는 함수이다.
PUTINTFIELD 버퍼에 Integer 데이터를 필드 순번으로 입력하는 함수이다.
PUTLONGFIELD 버퍼에 Long 데이터를 필드 순번으로 입력하는 함수이다.
PUTSTRSTRING 버퍼의 데이터를 text에 저장하는 함수이다.
PUTVARFIELD 버퍼에 String 데이터를 필드 순번으로 입력하는 함수이다.
TmaxError주어진 StrErr 메시지와 함께 tperrno에 해당하는 String 에러가 화면에 MsgBox로 출력되는 함수이다.

참고

atmi 함수와 필드키 함수에 대한 프로토타입 및 기능은 "Tmax Reference Guide""Tmax Application Development Guide"를 참고한다.

2.2. 함수

2.2.1. FdlErrorMsg

주어진 StrErr 메시지와 함께 fberrno를 화면에 MsgBox로 출력하는 함수이다.

  • 프로토타입

    Sub FdlErrorMsg(StrErr As String)
  • 파라미터

    파라미터설명
    StrErr에러 메시지이다.
  • 반환값

    메시지 윈도우를 출력한다.

  • 예제

    lret = fbput(ByVal lsendbuf, ByVal lfid, ByVal txtInput.text, ByVal 0)
    If lret = -1 Then
       FdlErrorMsg("fbput")
       error processing
       …
    End If
  • 관련함수

    TmaxError()

2.2.2. FilltpstartBuf

Tmax 시스템과 연결하기 위해 설정해야 하는 버퍼인 tpstart_t 구조체를 구성하는 함수이다.

  • 프로토타입

    Function FilltpstartBuf(sndbufp As Long, startinfop As tpstart_t) 
    As Long
  • 파라미터

    파라미터설명
    sndbufptpalloc 함수로 메모리에 할당된 버퍼를 의미한다.
    startinfoptpstart_t형으로 선언된 변수를 의미한다.
  • 예제

    Dim lsndbuf  As Integer
    Dim lret  As Integer
    Dim cinfo As tpstart_t
    
    lsndbuf = tpalloc("TPSTART", "", 0)
    If lsndbuf = 0 Then
        error processing
    End If
    
    cinfo.cltname = "tmax" + Chr(0)
    cinfo.usrname = "tmax" + Chr(0)
    cinfo.dompwd = "xamt" + Chr(0)
    cinfo.usrpwd = "batman" + Chr(0)
    cinfo.flags = TPUNSOL_HND
    
    lret = FilltpstartBuf(lsndbuf, cinfo)
    If ret < 0 Then
       error processing
    End If
    
    ret = tpstart(lsndbuf)
    If ret < 0 Then
       error processing
    End If
    …
  • 관련함수

    TmaxError()

2.2.3. GETCAR

CARRAY 버퍼에 String 데이터 text를 입력하는 함수이다.

  • 프로토타입

    Function GETCAR(ByVal Carptr&, text As String, Datalen As Long) 
    As Long
  • 파라미터

    파라미터설명
    CarptrFDL 버퍼의 포인터이다.
    text데이터를 의미한다.
    Datalen데이터 길이이다.
  • 반환값

    반환값설명
    1함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다.
  • 예제

    Dim lsendbuf As Long
    Dim lrecvbuf As Long
    Dim text As String
    Dim lret As Long
    Dim lrbuflen As Long
    …
    lsendbuf = tpalloc("CARRAY", "", 1024)
    lrecvbuf = tpalloc("CARRAY", "", 1024)
    …
    lret = tpcall(ByVal "SVC1", ByVal lsendbuf, ByVal DataLen&, lrecvbuf, lrbuflen, 
                  ByVal 0)
    …
    'CARRAY 버퍼에서는 반드시 데이터의 길이값을 입력해야 한다.
    lret = GETCAR(lsendbuf, text, lrbuflen)
    …
  • 관련함수

    GETINT(), GETLONG(), GETDOUBLE(), GETVAR(), GETSTR(), GETFLOAT(), GETSTR(), GETCHR()

2.2.4. GETCAR_BA

FIELD(FDL) 버퍼에 Field에 지정된 필드명으로 입력된 필드 순번 idx의 Image 데이터를 ByteArray에 저장하는 함수이다.

  • 프로토타입

    Function GETCAR_BA (ByVal Fdlptr&, Field As String, idx As Long, 
                        ByRef ByteArray() As Byte, datalen As Long) 
    As Long
  • 파라미터

    파라미터설명
    FdlptrFDL 버퍼의 포인터이다.
    Field필드명을 의미한다.
    idx필드 순번을 의미한다.
    ByteArray데이터를 의미한다.
    datalenByteArray의 길이이다.
  • 반환값

    반환값설명
    1함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다.
  • 예제

    Dim rbuffer(102400) As Byte
    Dim datalen As Long
    …
    lrecvbuf = tpalloc("FIELD", "", 102400)
    …
    lret = PUTCAR_BA(ByVal lsendbuf, "TP_BITMAP", 0, lbuffer, datalen)
    if lret < 0 then
        error processing
        …
    end if 
    …
    lret = tpcall(ByVal "FILEUP", ByVal lsendbuf, ByVal datalen&, lrecvbuf, 
                 lrbuflen, ByVal 0)
    lblComment.Caption = lblComment.Caption & " -> tpcall : " & lret
    If lret = -1 Then
        error processing
        …
    end If
    …
    lret = GETCAR_BA(ByVal lrecvbuf, "TP_BITMAP", 0, rbuffer, datalen)
    if lret < 0 then
        error processing
        …
    end if 
    …
  • 관련함수

    GETINT(), GETLONG(), GETDOUBLE(), GETCAR(), GETVAR(), GETFLOAT(), GETSTR(), GETCHR()

2.2.5. GETCHR

Tmax FDL 함수인 fbchg_tu()를 이용하여 지정한 nth에 해당하는 순번으로 Field에 지정된 필드명의 value값을 가져오는 함수이다. 이때 value값은 Char가 된다. fbget_tu()를 사용하므로 필드 순번(idx)의 데이터(char)를 가져온다.

  • 프로토타입

    Function GETCHR(ByVal Fdlptr&, ByVal Field As String, ByVal idx As Integer, 
                    ByRef data As String, ByVal datalen As Integer) 
    As Integer
  • 파라미터

    파라미터설명
    FldptrSTRING 버퍼의 포인터이다.
    Field필드명을 의미한다.
    idx필드 순번을 의미한다.
    data저장할 string 데이터이다.
    datalen저장할 string 데이터의 길이이다.
  • 반환값

    반환값설명
    1함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다.
  • 예제

    Dim lsendbuf As Long
    Dim lret As Long
    Dim chr As String               
    lsendbuf = fballoc(10, 100)
    Irecvbuf = fballoc(10, 100)
    …
    lret = tpcall(ByVal "SVC1", ByVal lsendbuf, ByVal DataLen&, lrecvbuf, lrbuflen, 
                  ByVal 0)
    …
    lret = GETSTR(lrecvbuf, "CHR", 0, chr, 1 )
    …
  • 관련함수

    GETINT(), GETLONG(), GETDOUBLE(), GETVAR(), GETSTR(), GETCAR(), GETFLOAT()

2.2.6. GETDOUBLE

FIELD(FDL) 버퍼에 Field에 지정된 필드명으로 입력된 필드 순번 idx의 Double 데이터를 dData에 저장하는 함수이다.

  • 프로토타입

    Function GETDOUBLE(ByVal Fdlptr&, Field As String, idx As Long, dData As Double) 
    As Long
  • 파라미터

    파라미터설명
    FdlptrFDL 버퍼의 포인터이다.
    Field필드명을 의미한다.
    idx필드 순번을 의미한다.
    dData데이터를 의미한다.
  • 반환값

    반환값설명
    1함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다.
  • 예제

    Dim lsendbuf As Long
    Dim lret As Long
    Dim doubledata As Double
    lsendbuf = tpalloc("FIELD ", "", 0)
    …
    lret = GETDOUBLE(ByVal lsendbuf, "DOUBLEDATA", 0, doubledata)
    …
  • 관련함수

    GETINT(), GETLONG(), GETVAR(), GETCAR(), GETFLOAT(), GETSTR(), GETCHR()

2.2.7. GETFLOAT

FIELD(FDL) 버퍼에 Field에 지정된 필드명으로 입력된 필드 순번 idx의 Single 데이터를 dData에 저장하는 함수이다.

  • 프로토타입

    Function GETFLOAT (ByVal Fdlptr&, Field As String, idx As Long, dData As Single) 
    As Long
  • 파라미터

    파라미터설명
    FdlptrFDL 버퍼의 포인터이다.
    Field필드명을 의미한다.
    idx필드 순번을 의미한다.
    dData데이터를 의미한다.
  • 반환값

    반환값설명
    1함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다.
  • 예제

    Dim lsendbuf As Long
    Dim lret As Long
    Dim doubledata As Single
    
    lsendbuf = tpalloc("FIELD ", "", 0)
    …
    lret = GETFLOAT (ByVal lsendbuf, "DOUBLEDATA", 0, doubledata)
    …
  • 관련함수

    GETINT(), GETLONG(), GETVAR(), GETCAR(), GETSTR(), GETCHR(), GETDOUBLE()

2.2.8. GETINT

FIELD(FDL) 버퍼에 Field에 지정된 필드명으로 입력된 필드 순번 idx의 Integer 데이터를 iData에 저장하는 함수이다.

  • 프로토타입

    Function GETINT(ByVal Fdlptr&, Field As String, idx As Long, iData As Integer) 
    As Long
  • 파라미터

    파라미터설명
    FdlptrFDL 버퍼의 포인터이다.
    Field필드명을 의미한다.
    idx필드 순번을 의미한다.
    iData데이터를 의미한다.

  • 반환값

    반환값설명
    1함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다.

  • 예제

    Dim lsendbuf As Long
    Dim lret As Long
    Dim intdata As Integer
                        
    lsendbuf = tpalloc("FIELD ", "", 0)
    
    lret = GETINT(ByVal lsendbuf, "INTDATA", 0, intdata)
    …
  • 관련함수

    GETLONG(), GETDOUBLE(), GETVAR(), GETCAR(), GETFLOAT(), GETSTR(), GETCHR()

2.2.9. GETLONG

FIELD(FDL) 버퍼에 Field에 지정된 필드명으로 입력된 필드 순번 idx의 Long 데이터를 lData에 저장하는 함수이다.

  • 프로토타입

    Function GETLONG(ByVal Fdlptr&, Field As String, idx As Long, lData As Long) 
    As Long
  • 파라미터

    파라미터설명
    FdlptrFDL 버퍼의 포인터이다.
    Field필드명을 의미한다.
    idx필드 순번을 의미한다.
    lData데이터를 의미한다.

  • 반환값

    반환값설명
    1함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다.

  • 예제

    Dim lsendbuf As Long
    Dim lret As Long
    Dim longdata As Long
    
    lsendbuf = tpalloc("FIELD ", "", 0)
    …
    lret = GETLONG(ByVal lsendbuf, "LONGDATA", 0, longdata)
    …
  • 관련함수

    GETINT(), GETDOUBLE(), GETVAR(), GETCAR(), GETFLOAT(), GETSTR(), GETCHR()

2.2.10. GETSTR

STRING 버퍼의 데이터를 text에 저장하는 함수이다.

  • 프로토타입

    Function GETSTR(ByVal strptr&, text As String) 
    As Long
  • 파라미터

    파라미터설명
    strptrSTRING 버퍼의 포인터이다.
    text데이터를 의미한다.

  • 반환값

    반환값설명
    1함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다.
  • 예제

    Dim lsendbuf As Long
    Dim lret As Long
    Dim text As String
                    
    lsendbuf = fballoc(10, 100)
    Irecvbuf = fballoc(10, 100)
    …
    lret = tpcall(ByVal "SVC1", ByVal lsendbuf, ByVal DataLen&, lrecvbuf, lrbuflen, 
                  ByVal 0)
    …
    lret = GETSTR(lrecvbuf, text)
    …
  • 관련함수

    GETINT(), GETLONG(), GETDOUBLE(), GETVAR(), GETCAR(), GETFLOAT(), GETSTR(), GETCHR()

2.2.11. GETVAR

FIELD(FDL) 버퍼에 Field에 지정된 필드명으로 입력된 필드 순번 idx의 String 데이터를 text에 저장하는 함수이다.

  • 프로토타입

    Function GETVAR(ByVal Fdlptr&, Field As String, idx As Long, text As String) 
    As Long
  • 파라미터

    파라미터설명
    FdlptrFDL 버퍼의 포인터이다.
    Field필드명을 의미한다.
    idx필드 순번을 의미한다.
    text데이터를 의미한다.
  • 반환값

    반환값설명
    1함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다.
  • 예제

    Dim lsendbuf As Long
    Dim lret As Long
    
    lsendbuf = tpalloc("FIELD ", "", 0)
    …
    lret = GETVAR(ByVal lsendbuf, "INPUT", 0, txtOutput.text)
    …
  • 관련함수

    GETINT(), GETLONG(), GETDOUBLE(), GETCAR(), GETFLOAT(), GETSTR(), GETCHR()

2.2.12. PUTCAR

CARRAY 버퍼에 String 데이터 text를 입력하는 함수이다.

  • 프로토타입

    Function PUTCAR(ByVal Carptr&, text As String, Datalen As Long) 
    As Long
  • 파라미터

    파라미터설명
    CarptrFDL 버퍼의 포인터이다.
    text데이터이다.
    Datalen데이터의 길이이다.
  • 반환값

    반환값설명
    -1 이외의 값함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다.
  • 예제

    Dim lret As Long 
    Dim DataLen As Long 
    lsendbuf = tpalloc("CARRAY", "", 1024) 
    'CARRAY 버퍼에서는 반드시 데이터의 길이값을 입력해야 한다. 
    
    DataLen = LenB(txtInput.text) 
    
    lret = PUTCAR(ByVal lsendbuf, txtInput.text, DataLen) 
    …

    STRING 버퍼는 시스템에서 제공하는 lstrcpy 함수를 사용하여 데이터를 버퍼에 실을 수 있다.

    Dim lsendbuf As Long
    Dim lret As Long
                    
    lsendbuf = tpalloc("STRING", "", 1024)
    lret = lstrcpy(ByVal lsendbuf, ByVal txtInput.text)
  • 관련함수

    PUTINT(), PUTLONG(), PUTDOUBLE(), PUTVAR(), PUTCAR(), PUTFLOAT(), PUTSTR()

2.2.13. PUTCAR_BA

FIELD 버퍼에 Image 데이터를 필드 순번으로 입력하는 함수이다. FIELD(FDL) 버퍼에 Field에 지정된 필드명으로 Image 데이터 ByteArray를 필드 순번 idx로 입력한다.

  • 프로토타입

    Function PUTCAR_BA(ByVal Fdlptr&, Field As String, idx As Long, ByteArray() 
                       As Byte, datalen As Long) 
    As Long
  • 파라미터

    파라미터설명
    FdlptrFDL 버퍼의 포인터이다.
    Field필드명을 의미한다.
    idx필드 순번을 의미한다.
    ByteArray데이터를 의미한다.
    datalenByteArray의 길이를 의미한다.
  • 반환값

    반환값설명
    -1 이외의 값함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다.
  • 예제

    Dim iSrc As Integer
    Dim lCopy As Long
    Dim lSize As Long
    Dim lbuffer() As Byte
    Dim datalen As Long
    …
    lsendbuf = tpalloc("FIELD", "", 102400)
    …
    iSrc = FreeFile
    Open ".\nmlogo.bmp" For Binary Access Read As iSrc
    lSize = LOF(iSrc)
    datalen = lSize
    Do
        If lSize > MAX_BUFFER Then
           lSize = lSize - MAX_BUFFER
           lCopy = MAX_BUFFER
        Else
           lCopy = lSize
        End If
            
        ReDim lbuffer(lCopy - 1)
        Get iSrc, , lbuffer
    Loop Until lCopy = lSize
        
    Close iSrc
     
    lret = PUTCAR_BA(ByVal lsendbuf, "TP_BITMAP", 0, lbuffer, datalen)
    if lret < 0 then
        error processing
        …
    end if 
    …
  • 관련함수

    PUTINT(), PUTLONG(), PUTDOUBLE(), PUTCAR(), PUTVAR(), PUTFLOAT(), PUTSTR(), PUTCHR()

2.2.14. PUTCHR

Tmax FDL 함수인 fbchg_tu()를 이용하여 지정한 nth에 해당하는 순번으로 fldName에 지정된 필드명에 value값을 저장하는 함수이다. 이때 value값은 Char가 된다. Fbchg_tu()를 사용하므로 필드 순번(nth)에 기존의 데이터가 있을 경우 주어진 데이터(value)로 변경이 되고, 필드 순번에 기존의 데이터가 없을 경우 주어진 데이터가 자동적으로 필드에 추가된다.

  • 프로토타입

    Function PUTCHR(ByVal Fdlptr&, ByVal Field As String, ByVal idx As Integer, 
                    ByRef data As String, ByVal datalen As Integer) 
    As Integer
  • 파라미터

    파라미터설명
    FldptrSTRING 버퍼의 포인터이다.
    Fieldt필드명을 의미한다.
    idx필드 순번을 의미한다.
    data저장할 string 데이터이다.
    datalen저장할 string 데이터의 길이이다.
  • 반환값

    반환값설명
    -1 이외의 값함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다.
  • 예제

    Dim lsendbuf As Long
    Dim lret As Long
    Dim chr As String
                    
    lsendbuf = fballoc(10, 100)
    chr = "a"
    …
    lret = PUTSTR(lsendbuf, "CHR", 0, chr, 1 )
    …
    Function PUTCHR(ByVal Fdlptr&, ByVal Field As String, ByVal idx As Integer, 
                    ByRef data As Char, ByVal datalen As Integer)
  • 관련함수

    PUTINT(), PUTLONG(), PUTDOUBLE(), PUTVAR(), PUTCAR(), PUTFLOAT(), PUTSTR()

2.2.15. PUTDOUBLE

FIELD 버퍼에 Double 데이터를 필드 순번으로 입력하는 함수이다. FIELD(FDL) 버퍼에 Field에 지정된 필드명으로 Double 데이터 dData를 필드 순번 idx로 입력한다.

  • 프로토타입

    Function PUTDOUBLE(ByVal Fdlptr&, Field As String, idx As Long, dData As Double) 
    As Long
  • 파라미터

    파라미터설명
    FdlptrFDL 버퍼의 포인터이다.
    Field필드명을 의미한다.
    idx필드 순번을 의미한다.
    dData데이터를 의미한다.
  • 반환값

    반환값설명
    -1 이외의 값함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다.
  • 예제

    Dim lsendbuf As Long
    Dim lret As Long
    Dim doubledata As Double
    
    lsendbuf = tpalloc("FIELD ", "", 0)
    …
    lret = PUTDOUBLE(ByVal lsendbuf, "DOUBLEDATA", 0, doubledata)
    …
  • 관련함수

    PUTINT(), PUTLONG(), PUTVAR(), PUTCAR(), PUTFLOAT(), PUTSTR(), PUTCHR()

2.2.16. PUTFLOAT

FIELD 버퍼에 Single 데이터를 필드 순번으로 입력하는 함수이다. FIELD(FDL) 버퍼에 Field에 지정된 필드명으로 Single 데이터 dData를 필드 순번 idx로 입력한다.

  • 프로토타입

    Function PUTFLOAT(ByVal Fdlptr&, Field As String, idx As Long, dData As Single) 
    As Long
  • 파라미터

    파라미터설명
    FdlptrFDL 버퍼의 포인터이다.
    Field필드명을 의미한다.
    idx필드 순번을 의미한다.
    dData데이터를 의미한다.
  • 반환값

    반환값설명
    -1 이외의 값함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다.
  • 예제

    Dim lsendbuf As Long
    Dim lret As Long
    Dim doubledata As Single
    
    lsendbuf = tpalloc("FIELD ", "", 0)
    …
    lret = PUTFLOAT(ByVal lsendbuf, "DOUBLEDATA", 0, doubledata)
    …
  • 관련함수

    PUTINT(), PUTLONG(), PUTVAR(), PUTCAR(), PUTDOUBLE(), PUTSTR(), PUTCHR()

2.2.17. PUTINT

FIELD 버퍼에 Integer 데이터를 필드 순번으로 입력하는 함수이다. FIELD(FDL) 버퍼에 Field에 지정된 필드명으로 Integer 데이터 iData를 필드 순번 idx로 입력한다.

  • 프로토타입

    Function PUTINT(ByVal Fdlptr&, Field As String, idx As Long, iData As Integer) 
    As Long
  • 파라미터

    파라미터설명
    FdlptrFDL 버퍼의 포인터이다.
    Field필드명을 의미한다.
    idx필드 순번을 의미한다.
    iData데이터를 의미한다.
  • 반환값

    반환값설명
    -1 이외의 값함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다.
  • 예제

    Dim lsendbuf As Long
    Dim lret As Long
    Dim intdata As Integer
                        
    lsendbuf = tpalloc("FIELD ", "", 0)
    …
    lret = PUTINT(ByVal lsendbuf, "INTDATA", 0, intdata)
    …
  • 관련함수

    PUTLONG(), PUTDOUBLE(), PUTVAR(), PUTCAR(), PUTFLOAT(), PUTSTR(), PUTCHR()

2.2.18. PUTLONG

FIELD 버퍼에 Long 데이터를 필드 순번으로 입력하는 함수이다. FIELD(FDL) 버퍼에 Field에 지정된 필드명으로 Long 데이터 lData를 필드 순번 idx로 입력한다.

  • 프로토타입

    Function PUTLONG(ByVal Fdlptr&, Field As String, idx As Long, lData As Long) 
    As Long
  • 파라미터

    파라미터설명
    FdlptrFDL 버퍼의 포인터이다.
    Field필드명을 의미한다.
    idx필드 순번을 의미한다.
    lData데이터를 의미한다.
  • 반환값

    반환값설명
    -1 이외의 값함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다.
  • 예제

    Dim lsendbuf As Long
    Dim lret As Long
    Dim longdata As Long
    
    lsendbuf = tpalloc("FIELD ", "", 0)
    …
    lret = PUTLONG(ByVal lsendbuf, "LONGDATA", 0, longdata)
    …
  • 관련함수

    PUTINT(), PUTDOUBLE(), PUTVAR(), PUTCAR(), PUTFLOAT(), PUTSTR(), PUTCHR()

2.2.19. PUTSTR

STRING 버퍼의 데이터를 text에 저장하는 함수이다.

  • 프로토타입

    Function PUTSTR(ByVal strptr&, text As String) 
    As Long
  • 파라미터

    파라미터설명
    strptrSTRING 버퍼의 포인터이다.
    text데이터를 의미한다.
  • 반환값

    반환값설명
    -1 이외의 값함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다.
  • 예제

    Dim lsendbuf As Long 
    Dim lret As Long 
    Dim text As String 
    
    lsendbuf = tpalloc("STRING", "", 1024) 
    … 
    lret = PUTSTR(lsendbuf, text) 
    …
  • 관련함수

    PUTINT(), PUTLONG(), PUTDOUBLE(), PUTVAR(), PUTCAR(), PUTFLOAT(), PUTCHR()

2.2.20. PUTVAR

FIELD 버퍼에 String 데이터를 필드 순번으로 입력하는 함수이다. FIELD(FDL) 버퍼에 Field에 지정된 필드명으로 String, 데이터 text를 필드 순번 idx로 입력한다.

  • 프로토타입

    Function PUTVAR(ByVal Fdlptr&, Field As String, idx As Long, text As String) 
    As Long
  • 파라미터

    파라미터설명
    FdlptrFDL 버퍼의 포인터이다.
    Field필드명을 의미한다.
    idx필드 순번을 의미한다.
    text데이터를 의미한다.
  • 반환값

    반환값설명
    -1 이외의 값함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다.
  • 예제

    Dim lsendbuf As Long
    Dim lret As Long
    
    lsendbuf = tpalloc("FIELD ", "", 0)
    …
    lret = PUTVAR(ByVal lsendbuf, "INPUT", 0, txtInput.text)
    …
  • 관련함수

    PUTINT(), PUTLONG(), PUTDOUBLE(), PUTCAR(), PUTFLOAT(), PUTSTR(), PUTCHR()

2.2.21. TmaxError

주어진 StrErr 메시지와 함께 tperrno에 해당하는 string 에러가 화면에 MsgBox로 출력되는 함수이다.

  • 프로토타입

    Sub TmaxError(StrErr As String)
  • 파라미터

    파라미터설명
    StrErr에러 메시지이다.

  • 반환값

    메시지 윈도우를 출력한다.

  • 예제

    Dim lsendbuf As Long
    Dim lrecvbuf As Long
    Dim lret As Long
    Dim lrbuflen As Long
        
    lsendbuf = tpalloc("CARRAY", "", 1024)
    lrecvbuf = tpalloc("CARRAY", "", 1024)
    lret = tpcall(ByVal "SVC1", ByVal lsendbuf, ByVal 0, lrecvbuf, lrbuflen, ByVal 0)
    
    If lret = -1 Then
       TmaxError ("tpcall (SVC1)")
    End If
  • 관련함수

    FdlErrorMsg()

2.3. 예제 프로그램

클라이언트 프로그램은 사용자의 요구를 받아서 서비스를 요청하고, 서버는 클라이언트에서 요구한 대로 Oracle 데이터베이스의 사원정보(EMP) 테이블에서 데이터를 입력, 수정, 조회 및 삭제한다.

2.3.1. 프로그램 구성

서버와 클라이언트 모두 환경설정이 되어 있어야 한다. TMAXDIR이나 포트 번호, 서버 IP 등의 환경설정이 이미 완료되어 있다고 가정하고 설정에 대한 내용은 생략한다.

다음의 예제 파일을 프로젝트에서 모듈로 추가한다.

  • <atmi.bas>

  • <fdl.bas>

  • <comm.bas>

  • <winapi.bas>

각각의 프로그램은 다음과 같은 파일들로 구성되어 있다.

  • 공통 프로그램

    프로그램 파일설명
    demo.f필드키 버퍼를 정의한 파일이다.
    tmax라이브러리 파일이다.
    tmconfig.mTmax 환경설정 파일이다.
  • 클라이언트 프로그램

    프로그램 파일설명
    EmployeeGrid.frm조회 결과를 보여주는 프로그램이다.
    EmployeeGrid.frx조회 결과를 보여주는 프로그램이다.
    EmployeeMgr.frmMain 프로그램이다. 조회, 수정, 삭제 및 입력 기능을 수행한다.
    MSSCCPRJ.SCCSource Code Control 파일이다.
    QA_4GL.vbg클라이언트 프로그램 그룹 프로젝트 파일이다.
    QA_4GL_Sample.exe클라이언트 프로그램 실행 파일이다.
    QA_4GL_Sample.vbp클라이언트 프로그램 프로젝트 파일이다.
    QA_4GL_Sample.vbw클라이언트 프로그램 workspace 파일이다.
    Atmi.basatmi 함수에 대한 프로토타입을 정의하는 파일이다.
    comm.bas사용자의 편의를 위한 매크로 정의 파일이다.
    fdl.bas필드키 함수에 대한 프로토타입을 정의하는 파일이다.
    winapi.basWindows에서 제공하는 함수 정의 파일이다.
  • 서버 프로그램

    프로그램 파일설명
    emp_c.mkMakefile이다.
    emp_c.pc서비스를 하는 서버 프로그램이다. AIX와 Oracle 9i를 사용했다.

2.3.2. 프로그램 특징

다음은 각 프로그램의 특징이다.

  • 클라이언트 프로그램

    기능설명
    Tmax 연결NULL 인자로 연결한다.
    버퍼 유형FIELD KEY 버퍼, 구조체 파일을 fdlc 유틸리티로 컴파일하여 'fdl' 파일의 생성이 필요하다.
    통신 유형tpcall()을 이용한 동기 통신을 보내는 버퍼와 받는 버퍼를 다르게 지정한다.
    트랜잭션 여부TMS에서 AutoTransaction 부여한다.
  • 서버 프로그램

    기능설명
    서비스FDLSELECT, FDLINSERT, FDLDELETE, FDLUPDATE를 작성한다.
    데이터베이스 지정Oracle 데이터베이스를 사용한다. 시스템 구성 파일의 SVRGROUP에 데이터베이스 정보를 지정한다.
    통신 유형tpcall()을 이용한 동기 통신을 보내는 버퍼와 받는 버퍼를 다르게 지정한다.
    트랜잭션 여부TMS에서 AutoTransaction 부여한다.

2.3.3. 공통 프로그램

DataBase EMP Table

다음은 Tmax EMP 데이터베이스(Oracle) 테이블의 예제이다.

EMPNO          NUMBER            NOT NULL         P1
ENAME          VARCHAR(16)
JOB            VARCHAR(16)
MGR            NUMBER
HIREDATE       DATE
SAL            NUMBER(7,2)
COMM           NUMBER(7,2)
DEPTNO         NUMBER

Tmax EMP 필드 테이블

다음은 Tmax EMP 필드 테이블의 예제이다.

<demo.f>

#For tmax demo employee program
EMPNO             7500                   long         -                        -
ENAME             7501                   string       -                        -
JOB               7502                   string       -                        -
MGR               7503                   long         -                        -
DATE              7504                   string       -                        -
SAL               7505                   float        -                        -
COMM              7506                   float        -                        -
DEPTNO            7507                   long         -                        -
E_TYPE            9009                   long         -                        -
E_CODE            9010                   long         -                        -
E_MSG             9011                   string       -                        -
E_TMP             9012                   long         -                        -

Tmax 환경설정

다음은 Tmax 환경설정 파일의 예제이다.

<tmconfig.m>

*DOMAIN
dom1       SHMKEY = 70000, MAXUSER = 200, MINCLH = 1, MAXCLH = 5,
           TPORTNO = 8888, BLOCKTIME = 200, TXTIME = 200

*NODE
tmax1      TMAXDIR = "/home/tmax",
           APPDIR = "/home/tmax/appbin",
           PATHDIR = "/home/tmax/path",
           TLOGDIR = "/home/tmax/log/tlog",
           SLOGDIR = "/home/tmax/log/slog"
           ULOGDIR = "/home/tmax/log/ulog"

*SVRGROUP
svg1        NODENAME = tmax1,
            DBNAME = ORACLE,
            OPENINFO = "ORACLE_XA+Acc=P/scott/tiger+SesTm=60",
            TMSNAME = svg1_tms

*SERVER
emp_c       SVGNAME = svg1, MIN = 1

*SERVICE
FDLSELECT   VRNAME = emp_c
FDLUPDATE   SVRNAME = emp_c
FDLDELETE   SVRNAME = emp_c
FDLINSERT   SVRNAME = emp_c

2.3.4. 클라이언트 프로그램

메인화면 Form

다음은 메인 화면 Form 디자인 화면이다.

다음은 예제에서 사용할 메인화면 Form 디자인 구성표이다.

컨트롤명컨트롤 종류비고
EmployeeMgrFormCaption="사원관리 프로그램"
LabelErr라벨Caption="오류"
BtnExit커맨드 버튼Caption="종료"
BtnIns커맨드 버튼Caption="입력"
BtnDel커맨드 버튼Caption="수정"
BtnUdt커맨드 버튼Caption="조회"
BtnSel커맨드 버튼 
EditName텍스트 박스 
EditEmpNo텍스트 박스 
EditDept텍스트 박스 
EditComm텍스트 박스 
EditSal텍스트 박스 
EditDate텍스트 박스 
EditMgr텍스트 박스 
EditJob텍스트 박스 

다음은 메인 화면 Form 디자인을 실행하기 위한 예제이다.

EmployeeMgr.frm Source
Option Explicit

Private Sub BtnDel_Click()

    Dim Isendbuf As Long
    Dim Irecvbuf As Long
    Dim Irbuflen As Long
    Dim Iret As Long
    Dim text As String
    Dim value As Long
    Dim dvalue As Double
    Dim svalue As Single
    Dim tx_b As Integer
    Dim txbool As Integer ' 트랜잭션이 시작되면 1, 아니면 0 '

    ' tpstart '
    tmaxStart

    ' 트랜잭션 시작 유무 초기화 '
    txbool = 0
                
    If EditEmpNo.text = "" Then
        MsgBox "사원번호를 입력해 주세요."
        tmaxEnd
        Exit Sub
    End If
    
    value = Trim(EditEmpNo.text)
    
  
    ' 보낼 데이터를 위한 버퍼 할당 '
    Isendbuf = fballoc(100, 1024)
    If Isendbuf = Null Then
        TmaxError ("fballoc")
        Call fbfree(Isendbuf)
        tmaxEnd
        Exit Sub
    End If
    
    ' 받을 데이터를 위한 버퍼 할당 '
    Irecvbuf = fballoc(100, 1024)
    If Irecvbuf = Null Then
        TmaxError ("fballoc")
        Call fbfree(Irecvbuf)
        tmaxEnd
        Exit Sub
    End If
            
    Iret = PUTLONG(ByVal Isendbuf, "EMPNO", 0, value)
    If Iret = -1 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    
    ' 트랜잭션 시작 '
    Iret = tx_begin
    txbool = 1
    If Iret < 0 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    
    ' 조회 서비스를 요청 '
    Iret = tpcall(ByVal "FDLDELETE", ByVal Isendbuf, ByVal 0, Irecvbuf, 
                  Irbuflen, ByVal 0)
    
    LabelErr.Caption = "sbuf = " & Isendbuf & ", rbuf = " & Irecvbuf
         
    If Iret = -1 Then
        TmaxError ("tpcall(SVC1)")
        ViewErr (Irecvbuf)
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    
    ' 트랜잭션 저장 '
    Iret = tx_commit
    If Iret < 0 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    Else
        txbool = 1
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
   
End Sub

Private Sub BtnExit_Click()
    End
End Sub

Private Sub BtnIns_Click()

    Dim Isendbuf As Long
    Dim Irecvbuf As Long
    Dim Irbuflen As Long
    Dim Iret As Long
    Dim text As String
    Dim value As Long
    Dim dvalue As Double
    Dim svalue As Single
    Dim lenL As Long
    Dim txbool As Integer ' 트랜잭션이 시작되면 1, 아니면 0 '

    ' tpstart '
    tmaxStart

    ' 트랜잭션 시작 유무 초기화 '
    txbool = 0
    
    If EditEmpNo.text = "" Then
        MsgBox "사원번호를 입력해 주세요."
        tmaxEnd
        Exit Sub
    End If
    
    ' 보낼 데이터를 위한 버퍼 할당 '
    Isendbuf = fballoc(100, 1024)
    If Isendbuf = Null Then
        TmaxError ("fballoc")
        Call fbfree(Isendbuf)
        tmaxEnd
        Exit Sub
    End If
    
    ' 받을 데이터를 위한 버퍼 할당 '
    Irecvbuf = fballoc(100, 1024)
    If Irecvbuf = Null Then
        TmaxError ("fballoc")
        Call fbfree(Irecvbuf)
        tmaxEnd
        Exit Sub
    End If
            
    Iret = PUTLONG(ByVal Isendbuf, "EMPNO", 0, Trim(EditEmpNo.text))
    If Iret = -1 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
        
    Iret = PUTVAR(ByVal Isendbuf, "ENAME", 0, Trim(EditName.text))
    If Iret = -1 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    
    Iret = PUTVAR(ByVal Isendbuf, "JOB", 0, Trim(EditJob.text))
    If Iret = -1 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    
    Iret = PUTLONG(ByVal Isendbuf, "MGR", 0, Trim(EditMgr.text))
    If Iret = -1 Then    ' 트랜잭션 시작 '
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    
    Iret = PUTVAR(ByVal Isendbuf, "DATE", 0, Trim(EditDate.text))
    If Iret = -1 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    
    svalue = Trim(EditSal.text)
    ' fbput, fbget_fldkey 함수의 정의는 comm.bas 파일에 정의되어 있습니다. '
    ' fbget_fldkey 함수는 필드명을 키값으로 변환해 줍니다. '
    Iret = fbput(ByVal Isendbuf, ByVal fbget_fldkey("SAL"), svalue, ByVal lenL)
    If Iret = -1 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    
    ' 밑의 주석부분은 주석 다음문과 같은 기능을 할 수 있습니다. '
    'svalue = Trim(EditComm.text)
    'Iret = fbput(ByVal Isendbuf, ByVal fbget_fldkey("COMM"), svalue, ByVal lenL)
    'If Iret = -1 Then
    '    FdlErrorMsg ("fbput")
    '    Exit Sub
    'End If
    
    ' 위의 주석과 같은 기능을 합니다. '
    Iret = PUTFLOAT(ByVal Isendbuf, "COMM", 0, Trim(EditComm.text))
    If Iret = -1 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    
    
    Iret = PUTLONG(ByVal Isendbuf, "DEPTNO", 0, Trim(EditDept.text))
    If Iret = -1 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    
    ' 트랜잭션 시작 '
    Iret = tx_begin
    txbool = 1
    If Iret < 0 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If

    ' 수정 서비스를 요청 '
    Iret = tpcall(ByVal "FDLINSERT", ByVal Isendbuf, ByVal 0, Irecvbuf, 
                  Irbuflen, ByVal 0)
    
    LabelErr.Caption = "sbuf = " & Isendbuf & ", rbuf = " & Irecvbuf
         
    If Iret = -1 Then
        TmaxError ("tpcall(SVC1)")
        ViewErr (Irecvbuf)
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    
    ' 트랜잭션 저장 '
    Iret = tx_commit
    If Iret < 0 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    Else
        txbool = 1
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If

End Sub
' Oracle에 대한 에러를 출력해주는 함수 '
' 조회 버튼을 클릭시 이벤트 핸들러 '
Private Sub BtnSel_Click()
    
    Hide
    ' 조회 결과 창 표시하기 '
    EmployeeGrid.Show

End Sub
' 수정 버튼을 클릭시 이벤트 핸들러 '
Private Sub BtnUdt_Click()

    Dim Isendbuf As Long
    Dim Irecvbuf As Long
    Dim Irbuflen As Long
    Dim Iret As Long
    Dim text As String
    Dim value As Long
    Dim dvalue As Double
    Dim svalue As Single
    Dim lenL As Long
    Dim txbool As Integer ' 트랜잭션이 시작되면 1, 아니면 0 '

    ' tpstart '
    tmaxStart

    ' 트랜잭션이 시작 유무 초기화 '
    txbool = 0
    
    If EditEmpNo.text = "" Then
        MsgBox "사원번호를 입력해 주세요."
        tmaxEnd
        Exit Sub
    End If
    
    ' 보낼 데이터를 위한 버퍼 할당 '
    Isendbuf = fballoc(100, 1024)
    If Isendbuf = Null Then
        TmaxError ("fballoc")
        Call fbfree(Isendbuf)
        tmaxEnd
        Exit Sub
    End If
    
    ' 받을 데이터를 위한 버퍼 할당 '
    Irecvbuf = fballoc(100, 1024)
    If Irecvbuf = Null Then
        TmaxError ("fballoc")
        Call fbfree(Irecvbuf)
        tmaxEnd
        Exit Sub
    End If
            
    Iret = PUTLONG(ByVal Isendbuf, "EMPNO", 0, Trim(EditEmpNo.text))
    If Iret = -1 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
        
    Iret = PUTVAR(ByVal Isendbuf, "ENAME", 0, Trim(EditName.text))
    If Iret = -1 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    
    Iret = PUTVAR(ByVal Isendbuf, "JOB", 0, Trim(EditJob.text))
    If Iret = -1 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    
    Iret = PUTLONG(ByVal Isendbuf, "MGR", 0, Trim(EditMgr.text))
    If Iret = -1 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    
    Iret = PUTVAR(ByVal Isendbuf, "DATE", 0, Trim(EditDate.text))
    If Iret = -1 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    
    
    svalue = Trim(EditSal.text)
    ' Declare Function fbput Lib "TMAX4GL.DLL" 
        (ByVal pFBUF As Long, ByVal fieldid As Long, pbuffer As Any, 
         ByVal Fieldlen As Long) As Long
    Iret = fbput(ByVal Isendbuf, ByVal fbget_fldkey("SAL"), svalue, ByVal lenL)
    If Iret = -1 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    
    svalue = Trim(EditComm.text)
    Iret = fbput(ByVal Isendbuf, ByVal fbget_fldkey("COMM"), svalue, ByVal lenL)
    If Iret = -1 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    
    Iret = PUTLONG(ByVal Isendbuf, "DEPTNO", 0, Trim(EditDept.text))
    If Iret = -1 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    
    ' 트랜잭션 시작 '
    Iret = tx_begin
    txbool = 1
    If Iret < 0 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    
    ' 수정 서비스를 요청 '
    Iret = tpcall(ByVal "FDLUPDATE", ByVal Isendbuf, ByVal 0, Irecvbuf, Irbuflen, 
                  ByVal 0)
    
    LabelErr.Caption = "sbuf = " & Isendbuf & ", rbuf = " & Irecvbuf
         
    If Iret = -1 Then
        TmaxError ("tpcall(SVC1)")
        ViewErr (Irecvbuf)
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    
    ' 트랜잭션 저장 '
    Iret = tx_commit
    If Iret < 0 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    Else
        txbool = 1
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    

End Sub
Private Sub ExitSub(txbool As Integer, Isendbuf As Long, Irecvbuf As Long)
    If txbool = 1 Then
        tx_rollback
    End If
    
    ' 할당된 버퍼 해제 '
    Call fbfree(ByVal Isendbuf&)
    Call fbfree(ByVal Irecvbuf&)
    
    ' tpend 실행 함수 '
    tmaxEnd
    
    Exit Sub
    
End Sub
' tpstart '
Private Sub tmaxStart()
    Dim ret As Integer
    
    ' 환경설정 파일을 불러옵니다. '
    ' atmi.bas 파일에 정의되어 있습니다. '
    ' Declare Function tmaxreadenv Lib "TMAX4GL.DLL" (ByVal envfile As String, 
                                                      ByVal label As String) 
                                                      As Long '
    ' 자세한 설명은 "Tmax Reference Guide"를 참고하십시오. '
    ret = tmaxreadenv("C:\tmax.env", "aix5l389")
    If ret < 0 Then
        TmaxError ("tmaxreadenv")
        Exit Sub
    End If
    
    ret = tpstart(ByVal 0&)
    If ret = -1 Then
        LabelErr.Caption = "tpstart error = " & gettperrno()
        TmaxError ("tpstart")
        Exit Sub
    Else
        LabelErr.Caption = "tpstart return value = " & ret & " tpstart success"
    End If
    
End Sub
' tpend '
Private Sub tmaxEnd()
    Dim ret As Integer
    ret = tpend()
    If ret = -1 Then
        LabelErr.Caption = "tpend error = " & gettperrno()
        TmaxError ("tpend")
        Exit Sub
    Else
        LabelErr.Caption = "tpreturn return value = " & ret
    End If
    
End Sub

Oracle 에러 출력

다음은 Oracle 에러 출력 화면이다.

다음은 Oracle 에러 출력 화면을 실행하는 데 필요한 환경설정의 예제이다.

' Oracle에 대한 에러를 출력해주는 함수 '
Private Sub ViewErr(ByVal a As Long)

    'E_TYPE          9009    long    -   -
    'E_CODE          9010    long    -   -
    'E_MSG           9011    string  -   -
    'E_TMP           9012    long    -   -

    Dim typeL, codeL, tmpL As Long
    Dim msgS As String
    Dim Iret As Integer
                
    ' Tmax FDL Reference Guide 참조 '
    ' comm.bas에 함수가 정의되어 있음 '
    Iret = fbget_tu(ByVal a, ByVal fbget_fldkey("E_TYPE"), 0, typeL, 0)
    If Iret = -1 Then
        FdlErrorMsg ("fbget_tu")
        Exit Sub
    End If
    
    Iret = fbget_tu(ByVal a, ByVal fbget_fldkey("E_CODE"), 0, codeL, 0)
    If Iret = -1 Then
        FdlErrorMsg ("fbget_tu")
        Exit Sub
    End If
    
    Iret = GETVAR(ByVal a, "E_MSG", 0, msgS)
    If Iret = -1 Then
        TmaxError ("ViewErr, GETVAR, E_MSG")
        Exit Sub
    End If
    
    Iret = fbget_tu(ByVal a, ByVal fbget_fldkey("E_TMP"), 0, tmpL, 0)
    If Iret = -1 Then
        FdlErrorMsg ("fbget_tu")
        Exit Sub
    End If
    ' 에러를 메시지 박스로 보여줌 '
    MsgBox ("Error Type : " & typeL & " ,Code : " & codeL & " ,Message : 
            " & msgS & " ,Tmp : " & tmpL)

End Sub

사원 조회 화면

다음은 사원 조회 화면 Form 디자인 화면이다.

다음은 조회 화면 Form 디자인 구성표이다.

컨트롤 이름컨트롤 종류수정이 필요한 프로퍼티
EmployeeGridFormCaption="사원정보 목록"
InfoText텍스트 박스MultiLine=True
BtnReturn커맨드 버튼Caption="돌아가기"

다음은 조회 화면 Form 디자인 화면을 실행하는 데 필요한 환경설정의 예제이다.

EmployeeGrid.frm Source LabelErr

Option Explicit
' 조회 창을 닫기 '
Private Sub BtnReturn_Click()
    Hide
    EmployeeMgr.Show

End Sub
' 조회 버튼 Click시 조회 리스트 결과를 보여줄 함수 '
Private Sub Form_Activate()

Dim Isendbuf As Long
    Dim Irecvbuf As Long
    Dim Irbuflen As Long
    Dim Iret As Integer
    Dim text As String
    Dim value As Long
    Dim dvalue As Double
    Dim svalue As Single
    Dim lenL As Long
    Dim initS, outputS As String
    Dim empnoS, enameS, jobS, mgrS, dateS, salS, commS, deptnoS As String
    Dim cntL As Long
    Dim eNo As Long
    Dim txbool As Integer ' 트랜잭션이 시작되면 1, 아니면 0 '

    ' tpstart '
    tmaxStart

    ' 트랜잭션 시작 유무 초기화 '
    txbool = 0
    
    initS = vbCrLf & vbTab & vbTab & vbTab & "***** 검색결과 *****" 
            & vbCrLf & vbTab & "===================================================" 
            & vbCrLf & vbTab & "사원번호 이름 직책 담당임원 입사일 봉급 COMM 부서" 
            & vbCrLf & vbTab & "===================================================" 
            & vbCrLf & vbCrLf
        
    If EmployeeMgr.EditEmpNo.text = "" Then
        MsgBox "사원번호를 입력해 주세요."
        Hide
        EmployeeMgr.Show
        Exit Sub
    End If
    
    ' 보낼 데이터를 위한 버퍼 할당 '
    Isendbuf = fballoc(100, 1024)
    If Isendbuf = Null Then
        TmaxError ("fballoc")
        Call fbfree(Isendbuf)
        tmaxEnd
        Exit Sub
    End If
    
    ' 받을 데이터를 위한 버퍼 할당 '
    Irecvbuf = fballoc(100, 1024)
    If Irecvbuf = Null Then
        TmaxError ("fballoc")
        Call fbfree(Irecvbuf)
        tmaxEnd
        Exit Sub
    End If
    
    ' 사원관리 Form에서 사원번호를 가지고 옵니다.
    eNo = Trim(EmployeeMgr.EditEmpNo.text)
    Iret = fbput(ByVal Isendbuf, ByVal fbget_fldkey("EMPNO"), eNo, ByVal lenL)
    If Iret = -1 Then
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
 
    ' 조회 서비스를 요청 '
    Iret = tpcall(ByVal "FDLSELECT", ByVal Isendbuf, ByVal 0, Irecvbuf, Irbuflen, 
                  ByVal 0)
    If Iret = -1 Then
        ViewErr (Irecvbuf)
        Call ExitSub(txbool, Isendbuf, Irecvbuf)
    End If
    
    cntL = fbkeyoccur(ByVal Irecvbuf, ByVal fbget_fldkey("EMPNO"))
    
    Dim i As Long
    
    For i = 0 To cntL - 1
        Iret = GETLONG(ByVal Irecvbuf, "EMPNO", i, value)
        If Iret = -1 Then
            TmaxError ("GETLONG(EMPNO)")
            Call ExitSub(txbool, Isendbuf, Irecvbuf)
        End If
        empnoS = value
    
        Iret = GETVAR(ByVal Irecvbuf, "ENAME", i, text)
        If Iret = -1 Then
            TmaxError ("GETVAR(ENAME)")
            Call ExitSub(txbool, Isendbuf, Irecvbuf)
        End If
        enameS = text
    
        Iret = GETVAR(ByVal Irecvbuf, "JOB", i, text)
        If Iret = -1 Then
            TmaxError ("GETVAR(JOB)")
            Call ExitSub(txbool, Isendbuf, Irecvbuf)
        End If
        jobS = text
    
        Iret = GETLONG(ByVal Irecvbuf, "MGR", i, value)
        If Iret = -1 Then
            TmaxError ("GETLONG(MGR)")
            Call ExitSub(txbool, Isendbuf, Irecvbuf)
        End If
        mgrS = value
    
        Iret = GETVAR(ByVal Irecvbuf, "DATE", i, text)
        If Iret = -1 Then
            TmaxError ("GETVAR(DATE)")
            Call ExitSub(txbool, Isendbuf, Irecvbuf)
        End If
        dateS = text
        
        ' SAL 데이터 필드에서 float 데이터를 가져옵니다. '
        ' comm.bas에 함수가 정의되어 있습니다. '
        Iret = fbget_tu(ByVal Irecvbuf, ByVal fbget_fldkey("SAL"), i, svalue, 0)
        If Iret = -1 Then
            FdlErrorMsg ("fbget_tu")
            Call ExitSub(txbool, Isendbuf, Irecvbuf)
        End If
        salS = svalue
    
        Iret = GETFLOAT(ByVal Irecvbuf, "COMM", i, svalue)
        If Iret = -1 Then
            TmaxError ("GETFLOAT(COMM)")
            Call ExitSub(txbool, Isendbuf, Irecvbuf)
        End If
        commS = svalue
        
        Iret = GETLONG(ByVal Irecvbuf, "DEPTNO", i, value)
        If Iret = -1 Then
            TmaxError ("GETLONG(DEPTNO)")
            Call ExitSub(txbool, Isendbuf, Irecvbuf)
        End If
        deptnoS = value & vbCrLf
    
        outputS = outputS & "       " & empnoS & vbTab & enameS & vbTab & jobS 
                                      & vbTab & mgrS & vbTab & dateS & vbTab 
                                      & salS & vbTab & commS & vbTab & deptnoS
    
    Next i
    
    InfoText.text = initS & outputS
    ' 반환된 데이터를 텍스트 박스에 출력 '
    LabelErr.Caption = "SAL = " & dvalue
    
    Call ExitSub(txbool, Isendbuf, Irecvbuf)

End Sub

Private Sub ExitSub(txbool As Integer, Isendbuf As Long, Irecvbuf As Long)
    If txbool = 1 Then
        tx_rollback
    End If
    
    ' 할당된 버퍼 해제 '
    Call fbfree(ByVal Isendbuf&)
    Call fbfree(ByVal Irecvbuf&)
    
    ' tpend 실행 함수 '
    tmaxEnd
    
    Exit Sub
    
End Sub

' tpstart '
Private Sub tmaxStart()
    Dim ret As Integer
    
    ' 환경설정 파일을 불러옵니다. '
    ' atmi.bas 파일에 정의되어 있습니다. '
    ' Declare Function tmaxreadenv Lib "TMAX4GL.DLL"(ByVal envfile As String, 
                                                    ByVal label As String) As Long '
    ' 자세한 설명은 "Tmax Reference Guide"를 참고하십시오. '
    ret = tmaxreadenv("C:\tmax.env", "aix5l389")
    If ret < 0 Then
        TmaxError ("tmaxreadenv")
        Exit Sub
    End If
    
    ret = tpstart(ByVal 0&)
    If ret = -1 Then
        LabelErr.Caption = "tpstart error = " & gettperrno()
        TmaxError ("tpstart")
        Exit Sub
    Else
        LabelErr.Caption = "tpstart return value = " & ret & " tpstart success"
    End If
    
End Sub
' tpend '
Private Sub tmaxEnd()
    Dim ret As Integer
    ret = tpend()
    If ret = -1 Then
        LabelErr.Caption = "tpend error = " & gettperrno()
        TmaxError ("tpend")
        Exit Sub
    Else
        LabelErr.Caption = "tpreturn return value = " & ret
    End If
End Sub
' Oracle에 대한 에러를 출력해주는 함수 '
Private Sub ViewErr(ByVal a As Long)

'E_TYPE          9009    long    -   -
'E_CODE          9010    long    -   -
'E_MSG           9011    string  -   -
'E_TMP           9012    long    -   -

    Dim typeL As Long
    Dim codeL As Long
    Dim msgS As String
    Dim tmpL As Long
    Dim Iret As Integer
            
    Iret = fbget_tu(ByVal a, ByVal fbget_fldkey("E_TYPE"), 0, typeL, 0)
           
    If Iret = -1 Then
        FdlErrorMsg ("fbget_tu")
        Exit Sub
    End If
    Iret = fbget_tu(ByVal a, ByVal fbget_fldkey("E_CODE"), 0, codeL, 0)
    If Iret = -1 Then
        FdlErrorMsg ("fbget_tu")
        Exit Sub
    End If
        
    Iret = GETVAR(ByVal a, "E_MSG", 0, msgS)
    Iret = fbget_tu(ByVal a, ByVal fbget_fldkey("E_TMP"), 0, tmpL, 0)
    If Iret = -1 Then
        FdlErrorMsg ("fbget_tu")
        Exit Sub
    End If
    MsgBox ("Error Type : " & typeL & " ,Code : " & codeL & " ,Message : "&msgS&" 
            ,Tmp : " & tmpL)
End Sub

2.3.5. 서버 프로그램

서비스 프로그램

다음은 서비스 프로그램의 예제이다.

<emp_c.pc>

#include <stdio.h>
#include <ctype.h>
#include <tuxinc/macro.h>
#include "../../fdl/demo_fdl.h"

EXEC SQL include sqlca.h;
EXEC SQL INCLUDE ORACA;
EXEC ORACLE  OPTION (ORACA=YES);
EXEC ORACLE  OPTION (RELEASE_CURSOR=YES);

#define INP   1
#define ORA   2
#define TMX   3
#define APP   4

EXEC SQL begin declare section;
int   h_empno;
char  h_ename[11];
char  h_job[10];
int   h_mgr;
char  h_date[11];
float h_sal;
float h_comm;
int   h_deptno;
EXEC SQL end declare section;

void svc_error(long type, long err_code, char *msg, long tmp);

FDLINSERT( TPSVCINFO *msg )
{
    FBUF *rcvbuf;
    int i, occurrence;
    rcvbuf = (FBUF *)msg->data;
    h_empno = h_mgr = h_sal = h_comm = h_deptno = 0;
            
    memset(h_ename, 0x00, sizeof(h_ename));
    memset(h_job, 0x00, sizeof(h_job));
    memset(h_date, 0x00, sizeof(h_date));
            
    occurrence = fbkeyoccur(rcvbuf, EMPNO);
            
    for (i=0; i< occurrence; i++){
         fbget_tu(rcvbuf, EMPNO, i, (char *)&h_empno, 0);
         fbget_tu(rcvbuf, MGR,   i, (char *)&h_mgr, 0);
         fbget_tu(rcvbuf, SAL,   i, (char *)&h_sal, 0);
         fbget_tu(rcvbuf, COMM,  i, (char *)&h_comm, 0);
         fbget_tu(rcvbuf, DEPTNO,i, (char *)&h_deptno, 0);
         fbget_tu(rcvbuf, ENAME, i, (char *)h_ename, 0);
         fbget_tu(rcvbuf, JOB  , i, (char *)h_job, 0);
         fbget_tu(rcvbuf, DATE , i, (char *)h_date, 0);
                        
         EXEC SQL INSERT 
         INTO emp(empno, ename, job, mgr, hiredate, sal,comm, deptno)
         VALUES (:h_empno, :h_ename, :h_job, :h_mgr, 
                 to_date(:h_date,'yyyymmdd'), :h_sal, :h_comm, :h_deptno );
     }
            
     if(sqlca.sqlcode != 0)
        goto LB_DBERROR;
            
     EXEC SQL WHENEVER SQLERROR
        goto LB_DBERROR;
            
     tpreturn(TPSUCCESS, 0L, (char *)rcvbuf, 0L, 0L);
            
     LB_DBERROR :
         EXEC SQL WHENEVER SQLERROR CONTINUE;
         svc_error(ORA, sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc, 0);
}


FDLDELETE( TPSVCINFO *msg )
{
     FBUF *rcvbuf;
     int i, occurrence;

     rcvbuf = ( FBUF *)msg->data;
     occurrence = fbkeyoccur(rcvbuf, EMPNO);

     for (i=0; i< occurrence; i++){
          fbget_tu (rcvbuf, EMPNO, i, (char *)&h_empno , 0);

          EXEC SQL DELETE
          FROM emp
          WHERE empno = :h_empno;
     }            
     if(sqlca.sqlcode != 0)
        goto LB_DBERROR;

     EXEC SQL WHENEVER SQLERROR
        goto LB_DBERROR ;

     EXEC SQL WHENEVER NOT FOUND
        goto LB_DBERROR ;

     tpreturn(TPSUCCESS, 0L, (char *)rcvbuf, 0L, 0L);

     LB_DBERROR :
        EXEC SQL WHENEVER SQLERROR CONTINUE;
        svc_error(ORA, sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc, 0);
}

FDLSELECT( TPSVCINFO *msg )
{
      FBUF *rcvbuf;
      FLDLEN fldlen;
      int i=0, ROWMEM=200, CHKROW=500;
      rcvbuf = (FBUF *)msg->data;

      if((rcvbuf=(FBUF *)tprealloc((char *)rcvbuf,ROWMEM*CHKROW))==NULL) {
          rcvbuf=(FBUF *)msg->data;
          goto LB_TMAXERROR ;
       }

       h_empno = h_mgr = h_sal = h_comm = h_deptno = 0;

       memset( h_ename, 0x00, sizeof( h_ename ) );
       memset( h_job, 0x00, sizeof( h_job ) );
       memset( h_date, 0x00, sizeof( h_date ) );

       fbget_tu( rcvbuf, EMPNO, 0, (char *)&h_empno, &fldlen);

       EXEC SQL DECLARE DB_CUR CURSOR FOR
       SELECT  nvl(empno,0), nvl(ename,' '), nvl(job,' '), 
               nvl(to_char(hiredate,'yyyymmdd'),' '),  nvl(mgr,0), 
               nvl(sal,0), nvl(comm,0), nvl(deptno,0)
       FROM  emp
       WHERE empno >= :h_empno-50 AND empno <= :h_empno+50;
       EXEC SQL OPEN DB_CUR;

       if(sqlca.sqlcode != 0)
          goto LB_DBERROR;
       
       EXEC SQL WHENEVER SQLERROR
          goto LB_DBERROR ;
       EXEC SQL WHENEVER NOT FOUND
          Do break ;

       while(1) {
          EXEC SQL FETCH DB_CUR
          INTO    :h_empno,
                  :h_ename,
                  :h_job,
                  :h_date,
                  :h_mgr,
                  :h_sal,
                  :h_comm,
                  :h_deptno;
          fbchg_tu(rcvbuf, EMPNO,  i,(char *)&h_empno, 0);
          fbchg_tu(rcvbuf, MGR,    i,(char *)&h_mgr, 0);
          fbchg_tu(rcvbuf, SAL,    i,(char *)&h_sal, 0);
          fbchg_tu(rcvbuf, DEPTNO, i,(char *)&h_deptno, 0);
          fbchg_tu(rcvbuf, COMM,   i,(char *)&h_comm, 0);
          fbchg_tu(rcvbuf, ENAME,  i,(char *)h_ename, 0);
          fbchg_tu(rcvbuf, JOB,    i,(char *)h_job, 0);
          fbchg_tu(rcvbuf, DATE,   i,(char *)h_date, 0);

          i++;
       }
       if (i < 1) goto LB_DBERROR;

       EXEC SQL CLOSE DB_CUR;
       tpreturn(TPSUCCESS, 0L, (char *)rcvbuf, 0L, 0L);

       LB_DBERROR :
            EXEC SQL WHENEVER SQLERROR CONTINUE;
            EXEC SQL CLOSE DB_CUR ;
            svc_error(ORA, sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc, 0L) ;

       LB_TMAXERROR :
            EXEC SQL WHENEVER SQLERROR CONTINUE;
            EXEC SQL CLOSE DB_CUR;
            svc_error(TMX, tperrno, "", 0L);
}

FDLUPDATE( TPSVCINFO *msg )
{      
       FBUF *rcvbuf ;
       int i, occurrence;
       rcvbuf = (FBUF *)msg->data;
       h_empno = h_mgr = h_sal = h_comm = h_deptno = 0;

       memset( h_ename, 0x00, sizeof( h_ename ) );
       memset( h_job, 0x00, sizeof( h_job ) );
       memset( h_date, 0x00, sizeof( h_date ) );

       occurrence = fbkeyoccur(rcvbuf, EMPNO);
            
       for (i=0; i< occurrence; i++){
            fbget_tu ( rcvbuf, EMPNO, i, (char *)&h_empno, 0);
            fbget_tu ( rcvbuf, ENAME, i, (char *)h_ename, 0);
            fbget_tu ( rcvbuf, JOB, i, (char *)h_job, 0);
            fbget_tu ( rcvbuf, MGR, i, (char *)&h_mgr, 0);
            fbget_tu ( rcvbuf, SAL, i, (char *)&h_sal, 0);
            fbget_tu ( rcvbuf, COMM, i, (char *)&h_comm,0);
            fbget_tu ( rcvbuf, DEPTNO, i, (char *)&h_deptno,0);
            fbget_tu ( rcvbuf, DATE, i, (char *)h_date, 0);

            EXEC SQL UPDATE emp
            SET ename = nvl(:h_ename, ename),
                job   = nvl(:h_job, job),
                mgr   = :h_mgr,
                hiredate  = nvl(to_date(:h_date,
                                'yyyymmdd'),hiredate),
                sal   = :h_sal,
                comm  = :h_comm,
                deptno = :h_deptno
            WHERE empno = :h_empno;
            
            if(sqlca.sqlcode != 0)
               goto LB_DBERROR;
                        
            EXEC SQL WHENEVER SQLERROR
               goto LB_DBERROR;

            EXEC SQL WHENEVER NOT FOUND
               goto LB_DBERROR;
       }
       tpreturn(TPSUCCESS, 0L, (char *)rcvbuf, 0L, 0L);

       LB_DBERROR :
            EXEC SQL WHENEVER SQLERROR CONTINUE;
            svc_error(ORA, sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc, 0L) ;
}

/*********************************************************************
 * 에러처리 :  서비스에서 오류가 발생하면 그 오류를 버퍼에 넣어 클라이언트로 보내준다. 
 ********************************************************************/
void svc_error(long type, long err_code, char *msg, long tmp) {
        FBUF *transf;
        char *svcname;
        char err_msg[100];
        char temp[100];
        int i = 0;

        printf("type     ==>[%ld]\n", type); 
        printf("err_code ==>[%ld]\n", err_code);
        printf("msg      ==>[%s]\n",  msg);            
        strcpy(err_msg, msg);

        if ((transf = (FBFR *)tpalloc("FML", NULL, 0)) == NULL) {
             printf("tpalloc failed! errno = %d\n", tperrno);
        }

        switch(type) {
             case INP:
                  switch(err_code) {
                         case -1000:
                               strcpy(err_msg,"해당 사용자에게 권한이 없습니다.");
                               break;
                         default:
                               strcpy(err_msg,
                                      "Input Error Message가 등록되어 있지 않습니다.");
                  }
                  break;
             case ORA:
                  if (strlen(err_msg)== 0) 
                      strcpy(err_msg, sqlca.sqlerrm.sqlerrmc);
                      break; 
             case TMX:
                  if (strlen(err_msg)== 0) 
                      strcpy(err_msg, tpstrerror(tperrno));
                      break;
             case APP:
                  if (strlen(err_msg)== 0) {
                      /* err_mssg=""이면 오류메세지를 setting한다. ******/
                      switch(err_code) {
                            case -500:            /* SYSTEM 관련 오류 */
                                  strcpy(err_msg,"File 생성 오류입니다.");
                                  break;
                            case -502:            
                                  strcpy(err_msg,"내부 서비스를 호출하지 못했습니다.");
                                  break;
                            case -504:
                                  strcpy(err_msg, "소켓 통신 오류입니다.");
                                  break;
                            case -505: /* 다른 transation에서 수정되었을 경우 MSG처리*/
                                    /* "조회 이후에 다른 곳에서 [%s]자료가 변경되었습니다.
                                    \n\n다시 조회한 후 처리하십시오.": CLIENT에서 처리*/
                                    strcpy(err_msg,"이 없습니다.");
                                    break;
                            case -5002: 
                                    strcpy(err_msg, "전산실에 문의하십시오.");
                                    break;
                            default:
                                    strcpy(err_msg, 
                                 "Application Error Message가 등록되어 있지 않습니다.");
                        }
                   }
                   break;
            }

            /* ROLLBACK */
            EXEC SQL WHENEVER SQLERROR CONTINUE;
            EXEC SQL ROLLBACK;

            fbchg_tu ( transf, E_TYPE, i, (char *)&type,0);
            fbchg_tu ( transf, E_CODE, i, (char *)&err_code,0);
            fbchg_tu ( transf, E_MSG, i, (char *)err_msg,0);
            fbchg_tu ( transf, E_TMP, i, (char *)&tmp,0);

            tpreturn(TPFAIL, 0, (char *)transf, 0L, 0L);
}

Makefile

다음은 emp_c.pc 소스를 Tmax 애플리케이션으로 만드는 Makefile의 예제이다.

<emp_c.mk>

include $(ORACLE_HOME)/precomp/lib/env32.mk
ORALIBDIR = $(LIBHOME)
ORALIB = -L/home/oracle/OraHome/lib32/ -lclntsh  -lld -lm `cat 
          /home/oracle/OraHome/lib32/sysliblist`  -lm  -lc_r -lpthreads
TARGET = emp_c
APOBJS = emp_c.o 
NSDLOBJ = $(TMAXDIR)/lib/sdl.o
#CC
CC=cc

#Oracle
LIBS = -lsvr -loras

OBJS = $(APOBJS) $(SVCTOBJ) 
SVCTOBJ = $(TARGET)_svctab.o 

CFLAGS  = -q32 -O -I$(TMAXDIR)
LDFLAGS = -brtl
APPDIR  = $(TMAXDIR)/appbin
SVCTDIR = $(TMAXDIR)/svct
TMAXLIBDIR  = $(TMAXDIR)/lib
 #
.SUFFIXES : .c

.c.o: 
     $(CC) $(CFLAGS) $(LDFLAGS) -c $<

all: $(TARGET) 

$(TARGET): $(OBJS)
     $(CC) $(CFLAGS) $(LDFLAGS) -L$(TMAXLIBDIR) -o $(TARGET) 
     -L$(ORALIBDIR) $(ORALIB) $(OBJS) $(LIBS) $(NSDLOBJ)
     mv $(TARGET) $(TMAXDIR)/appbin

$(APOBJS): $(TARGET).pc
     proc iname=emp_c include=$(TMAXDIR) 
     define=__LINUX_ORACLE_PROC__
     $(CC) $(CFLAGS) $(LDFLAGS) -c $(TARGET).c

$(SVCTOBJ):
     touch $(SVCTDIR)/$(TARGET)_svctab.c
     $(CC) $(CFLAGS) $(LDFLAGS) -c $(SVCTDIR)/$(TARGET)_svctab.c
#
clean:
     -rm -f *.o core $(TARGET) $(TARGET).lis