.NET을 이용해서 C++/C 로 만든 Windows DLL들을 호출하는 방법이 있다.

그 방법은 DllImport 라고 하는 System.Runtime.InteropServices 네임스페이스의 프로퍼티 클래스를 사용하면된다.

간단한 사용예는 아래와 같다.

[DllImport("twainDSM.dll")]
private static extern TwRC DSMSetParent( [In, Out] TwIdentity origin, IntPtr zeroptr, TwDG dg, TwDAT dat, TwMSG msg, ref IntPtr refptr );

DllImport 에 원하는 DLL을 선언하고, static extern 메소드에 걸어주면 된다.
만일 입출력이 겸해지는 파라미터 인 경우 [In,Out] 을 사용하면 되고, 입력이면 그대로 [in]을 쓰면 된다.

그런데, 하나의 DLL 함수에 여러가지 형태로 정의하고 싶은 경우가 있다.
입력값이 미묘하게 틀린경우 그에 맞추기만 하면 되는 경우다.

예를 들면 TWAIN에서 제공하는 DLL 함수 중 DSM_Entry 라는 함수가 있다.

TW_UINT16 FAR PASCAL DSM_Entry( pTW_IDENTITY pOrigin,
                                  pTW_IDENTITY pDest,
                                  uint    DG,
                                  uint    DAT,
                                  uint    MSG,
                                 (void**)    pData);

그 형태는 위와 같다. 즉 첫번째 두번째 파라미터는 규격화 된 것이지만, 맨 마지막 같은 경우에는 특정한 형태가 없는 값이다. 또, 두번째 파라미터가 null 인 경우도 있을 것이다. 호출하는 방법에 따라 그 방법이 다양한데, 이것을 C#에서는 아래와 같이 표현 할 수 있다.

[DllImport("twainDSM.dll", EntryPoint="#1")]
private static extern TwRC DSM_Entry1( [In, Out] TwIdentity origin, IntPtr zeroptr, TwDG dg, TwDAT dat, TwMSG msg, ref IntPtr refptr );

[DllImport("twainDSM.dll", EntryPoint="#1")]
private static extern TwRC DSM_Entry2( [In, Out] TwIdentity origin, IntPtr zeroptr, TwDG dg, TwDAT dat, TwMSG msg, [In, Out] TwIdentity idds );

[DllImport("twainDSM.dll", EntryPoint="#1")]
private static extern TwRC DSM_Entry3( [In, Out] TwIdentity origin, IntPtr zeroptr, TwDG dg, TwDAT dat, TwMSG msg, [In, Out] TwStatus dsmstat );

위의 첫번째 예에서 달라진 것은 EntryPoint를 명시한 것이다. 즉 DLL에서 제공하는 첫번째 메소드를 쓴다는 것이다. 함수 이름이야 뭐가 되든간에, 무조건 DLL에서 제공하는 첫번째 함수를 쓴다는 것이다. 파라미터도 최대한 DSM_Entry의 함수를 그대로 따르되, 두번째 파라미터가 Null 이라면 zeroptr에 IntPtr.Zero를 넣는 것이다. 그리고 맨 마지막 파라미터 같이 다양한 형태로 때려 박는 스타일일때는 그에 필요한 형을 그대로 집어넣는다. 그러면 .NET에서 DLL 함수와 연결할때, 알아서 해당 부분을 (void **)로써 제공할 뿐이라는 것이다. 다른 것들도 마찬가지로, 각 변수들의 크기만 잘 맞출 수 있다면 ( int 면 4바이트, short 이면 2바이트 등등) 그게 무슨 값이든 상관 없이 적용할 수 있다는 것이다.

Unmanaged .NET은 하면 할 수록 나름 매력이 솔솔 풍기는 기분이다.

728x90

+ Recent posts