3. Implementation/COM & ActiveX

형식 라이브러리를 통해 VB에서 C DLL을 보다 쉽게 사용할 수 있도록 하는 방법

SSKK 2009. 3. 5. 04:50
아래는 VC++로 작성된 COM 개체의 메소드를 작성할 때, Visual Basic에서 보다 쉽게 사용할 수 있도록 enum 형을 제공하는 방법에 대한 것이다.

------------------------------------------------

형식 라이브러리는 자동화에 사용되는 복합 문서 파일(.tlb 파일)입니다. 여기에는 자동화 서버에서 해당 클라이언트에 제공하는 형식, 개체, 모듈 및 인터페이스에 대한 중요한 정보가 들어 있습니다. 다행히도 형식 라이브러리를 사용하기 위해서는 서버가 자동화 서버가 아니어도 됩니다. 사실 대부분의 C DLL은 자동화 서버가 아닙니다. 필요한 작업은 C DLL이 형식 라이브러리에서 함수를 모듈 멤버로 선언하는 것뿐입니다. Visual Basic과 같은 자동화 클라이언트는 이 정보를 읽고 마치 이 정보가 개체인 것처럼 이 정보에 바인딩할 수 있습니다. Visual Basic이 자동으로 모든 작업을 수행하므로 Declare 문을 사용하거나 힘들게 상수를 기억하지 않아도 됩니다.

DLL의 형식 라이브러리를 만들면 여러 가지 이점이 있습니다. 그 중에서 가장 중요한 것은 형식 안정성이 향상된다는 것입니다. 뿐만 아니라 Visual Basic이 초기 바인딩을 사용하여 함수에 자동으로 바인딩하므로 성능이 향상된다는 이점도 있습니다. 반면에 Declare 문은 모두 런타임에 바인딩됩니다. 또한 Visual Basic 프로그래머에 DLL이 표시되는 방법을 더 잘 제어할 수 있습니다. 형식 라이브러리를 사용하면 함수 및 매개 변수에 열거형과 UDT(사용자 정의 형식) 같은 유용한 추가 기능뿐 아니라 Visual Basic 이름을 제공할 수 있습니다.

현재 형식 라이브러리는 IDL(인터페이스 정의 언어)이나 ODL(개체 설명 언어)로 작성된 스크립트를 사용하여 만듭니다. 이러한 스크립트는 Visual Studio와 함께 제공되는 MkTypLib.EXE나 MIDL.EXE를 통해 컴파일됩니다. 프로젝트를 컴파일할 때 DLL 프로젝트와 연결하는 모든 ODL 파일은 MIDL을 통해 자동으로 컴파일되므로 Visual C++에서는 형식 라이브러리를 만드는 작업 중 일부 작업만 수행합니다.
 

단계별 예제 - DLL 및 형식 라이브러리 만들기

  1. Visual C++ 5.0을 열고 파일|새로 만들기를 선택합니다. 프로젝트 탭에서 "Win32 동적 연결 라이브러리"를 선택하고 프로젝트 이름을 "TLBSamp"로 지정합니다.
  2. 파일|새로 만들기를 다시 선택합니다. 파일 탭에서 "C++ 소스 파일"을 선택하고 파일 이름을 "TLBSamp.c"로 지정한 다음 확인을 누릅니다.
  3. 2단계를 다시 반복하고 이번에는 파일 형식으로 "텍스트 파일"을 선택합니다. 파일 이름을 각각 "TLBSamp.def"와 "TLBSamp.odl"로 지정합니다.
  4. 그런 다음 TLBSamp.c에 다음 코드를 추가합니다.
     

    #include <windows.h>

     

    // MyDll_ReverseString -- Reverses the characters of a given string

    void __stdcall MyDll_ReverseString(LPSTR lpString)

    {

        _strrev(lpString);

    }

     

    // MyDLL_Rotate -- Returns bit rotation of 32-bit integer value

    int __stdcall MyDll_Rotate(int nVal, int nDirect, short iNumBits)

    {

        int nRet = 0;

     

        if((iNumBits < 1) || (iNumBits > 31))

            return nRet;

     

        switch(nDirect)

        {

        case 0:

            // Rotate nVal left by iNumBits

            nRet = (((nVal) << (iNumBits)) |

                ((nVal) >> (32-(iNumBits))));

            break;

        case 1:

            // Rotate nVal right by iNumBits

            nRet = (((nVal) >> (iNumBits)) |

                ((nVal) << (32-(iNumBits))));

            break;

        }

     

        return nRet;

    }


  5. 함수를 내보낼 수 있게 하려면 TLBSamp.def에 다음 코드를 추가합니다.
          LIBRARY TLBSamp
          DESCRIPTION 'Microsoft KB Sample DLL'
          EXPORTS
            MyDll_ReverseString
            MyDll_Rotate
    
    						
  6. TLBSamp.odl에 다음 코드를 추가하여 형식 라이브러리에서 함수를 선언합니다.
          
     

    // This is the type library for TLBSamp.dll

    [

        // Use GUIDGEN.EXE to create the UUID that uniquely identifies

        // this library on the user's system. NOTE: This must be done!!

        uuid(F1B9E420-F306-11d1-996A-92FF02C40D32),

        // This helpstring defines how the library will appear in the

        // References dialog of VB.

        helpstring("KB Sample: Make your C DLL More Accessible"),

        // Assume standard English locale.

        lcid(0x0409),

        // Assign a version number to keep track of changes.

        version(1.0)

    ]

    library TLBSample

    {

     

        // Define an Enumeration to use in one of our functions.

        typedef enum tagRotateDirection

        {

            tlbRotateLeft=0,

            tlbRotateRight=1

        }RotateDirection;

     

        // Now define the module that will "declare" your C functions.

        [

            helpstring("Sample functions exported by TLibSamp.dll"),

            version(1.0),

            // Give the name of your DLL here.

            dllname("TLBSamp.dll")

        ]

        module MyDllFunctions

        {

     

            [

                // Add a description for your function that the developer can

                // read in the VB Object Browser.

                helpstring("Returns the reverse of a given string."),

                // Specify the actual DLL entry point for the function. Notice

                // the entry field is like the Alias keyword in a VB Declare

                // statement -- it allows you to specify a more friendly name

                // for your exported functions.

                entry("MyDll_ReverseString")

            ]

            // The [in], [out], and [in, out] keywords tell the Automation

            // client which direction parameters need to be passed. Some

            // calls can be optimized if a function only needs a parameter

            // to be passed one-way.

            void __stdcall ReverseString([in, out] LPSTR sMyString);

     

            [

                helpstring("Rotates a Long value in the given direction."),

                entry("MyDll_Rotate")

            ]

            // Besides specifying more friendly names, you can specify a more

            // friendly type for a parameter. Notice the Direction parameter

            // has been declared with our enumeration. This gives the VB

            // developer easy access to our constant values.

            int __stdcall BitRotate([in] int Value,

                [in] RotateDirection Direction,

                [in] short Bits);

     

        } // End of Module

    }; // End of Library


  7. 빌드 메뉴에서 "모두 다시 빌드"를 선택하여 DLL과 형식 라이브러리를 컴파일합니다. 컴파일이 완료되면 새 DLL(TLBSamp.dll)을 Visual Basic 디렉터리로 복사하여 테스트합니다.
참고: 편의상 형식 라이브러리를 DLL에 리소스로 포함할 수 있습니다. 이렇게 하면 별도의 TLB 파일을 Visual Basic 개발자에게 배포하지 않아도 됩니다.

라이브러리를 리소스로 추가하려면 다음과 같이 하십시오.
  1. 파일|새로 만들기를 선택합니다. 파일 탭에서 "텍스트 파일"을 선택하고 파일 이름을 "TLBSamp.rc"로 지정한 다음 확인을 누릅니다.
  2. 텍스트 창이 나타나면 다음 줄을 추가합니다.

    1 typelib TLBSamp.tlb
  3. 파일을 저장하고 DLL을 다시 컴파일합니다. 컴파일이 완료되면 새 DLL(TLBSamp.dll)을 Visual Basic 디렉터리로 복사하여 테스트하고 이전 파일을 덮어쓸 것인지 묻는 메시지가 나타나면 파일을 덮어씁니다.
 

단계별 예제 - Visual Basic 테스트 응용 프로그램

  1. DLL과 형식 라이브러리를 테스트하려면 Visual Basic 5.0을 열고 표준 프로젝트를 새로 만듭니다. 기본적으로 Form1이 만들어집니다.
  2. 프로젝트 메뉴에서 참조를 선택하여 참조 대화 상자를 불러온 다음 찾아보기를 눌러 새 형식 라이브러리(또는 라이브러리를 리소스로 추가한 경우 DLL)를 찾습니다. 새 형식 라이브러리를 찾은 다음 확인을 누릅니다. Visual Basic은 사용자가 라이브러리를 처음 참조할 때 해당 라이브러리를 자동으로 등록합니다. 참조 목록에서 라이브러리("KB 예제: C DLL을 보다 쉽게 사용할 수 있도록 하기)가 선택되어 있는지 확인한 다음 대화 상자를 닫습니다.
  3. F2 키를 눌러 개체 브라우저를 불러옵니다. 라이브러리(TLBSamp)가 Visual Basic 프로젝트에 추가되었으며, 이제 함수를 네이티브 Visual Basic 함수처럼 호출할 수 있습니다. 개발자가 BitRotate 함수에 Direction 매개 변수를 입력하면 열거형 목록이 드롭다운됩니다.
  4. Form1에 CommandButton을 추가하고 단추의 Click 이벤트에 다음 코드를 추가합니다.
          
     

    ' VBScript source code

    Private Sub Command1_Click()

        Dim n1 As Long, n2 As Long, nTmp As Long

        Dim sTest As String, sMsg As String

     

        sTest = "Hello World!"

        n1 = 100

     

        ReverseString sTest

        sMsg = sTest & " | "

        ReverseString sTest

        sMsg = sMsg & sTest & vbCrLf

     

        nTmp = BitRotate(n1, tlbRotateLeft, 2)

        n2 = BitRotate(nTmp, tlbRotateRight, 2)

        sMsg = sMsg & Str$(n1) & " : " & Str$(nTmp) & " : " & Str$(n2)

     

        MsgBox sMsg

    End Sub


  5. 이제 F5 키를 눌러 IDE에서 vb5allB 프로젝트를 실행합니다.

    참고: 오류 메시지가 나타나면 Visual Basic이 DLL을 찾을 수 없기 때문일 수 있습니다. 테스트 응용 프로그램을 실행하기 전에 Visual Basic 디렉터리나 시스템 경로에 DLL을 복사했는지 확인하십시오

출처 : http://support.microsoft.com/kb/189133