ATL 기반 In-Process Server를 이용하여 코드를 프로그래밍하는 것은 경우에 따라서는 일을 간단하게 마무리지을 수도 있지만 때로는 깊은 생각을 필요로 하기도 한다. 특히, 하나 이상의 다중 스레드를 이용하여야 하는 경우가 더욱 그런데, ATL Simple Object의 FinalConstruct와 FinalRelease 메서드의 재정의를 이용하여 스레드를 관리하는 방법을 처음 써보았다. 하지만 문제점 투성이였고 이상한 버그가 계속 나타났다.

그래서 생각하게 된 것이 ATL에서 제공하는 간단한 Win32 Window Implementation 클래스를 활용하는 방법이다. 클라이언트에서 데이터를 주거나 받기 위한 목적으로 In-Process Server를 활용하는 과정이었으므로 WSAAsyncSelect를 이용하기에도 편리했다. WSAAsyncSelect로 ATL Window의 핸들을 넘겨주고 ATL Window에서는 해당 메시지에 대한 처리 핸들러만 추가하면 그 다음은 내가 종전에 일반 스레드로 구현하였던 코드를 그대로 가져가기만 하면 되는 것이라서 마이그레이션에 특별히 어려운 점도 없었다.

이렇게하여 select() 함수를 통한 I/O Multiplexing 기능 개선과 함께 더 호환성이 좋은 이벤트 시스템을 구축할 수 있었다.

Creative Commons License
Creative Commons License
남정현 이 작성.

당신의 의견을 작성해 주세요.

[로그인][오픈아이디란?]
오픈아이디로만 댓글을 남길 수 있습니다
CoClassAttribute는 인터페이스에 특별한 능력을 부여한다. 이름 그대로 특정 인터페이스와 단짝이 되는 형식을 지정한다는 뜻이다. 원래는 COM 상호 운용성을 위하여 추가된 기능이지만 이 CoClassAttribute의 능력으로 일어나는 재미있는 현상을 살펴보기로 한다.

CoClassAttribute는 단독으로 사용되지 않으며 GuidAttribute와 ComImportAttribute와 함께 쓰인다. 이 세 Attribute를 함께 조합하여 COM에서 가져온 CoClass가 설정된 인터페이스임을 뜻하는 것이 원래의 의미이지만 COM에서 가지고 온것이 아니어도 가능한 조합이다.

using System;
using System.Runtime.InteropServices;

[ComImport]
[CoClass(typeof(Test))]
[Guid("DE1305DB-7814-4e94-9593-AC76DD58C24F")]
public interface ITest
{
  int Add(int a, int b);
  int Sub(int a, int b);
  long Mul(int a, int b);
  double Div(int a, int b);
  int Mod(int a, int b);
}

public class Test : ITest
{
  int Add(int a, int b) { return a + b; }
  int Sub(int a, int b) { return a - b; }
  long Mul(int a, int b) { return (long)(a * b); }
  double Div(int a, int b) { return (double)(a / b); }
  int Mod(int a, int b) { return a % b; }
}

여기서 우리는 Test 클래스의 인스턴스를 생성하는 것이 당연하다고 생각되지만 ITest의 생성자를 호출해볼까 한다. 불가능한 일일까?

public class Test
{
  public static void Main()
  {
     ITest oTest = new ITest();
     Console.WriteLine(oTest.ToString());
  }
}


위와 같은 코드를 호출하였을 때 무엇이 나올까? 그렇다. CoClassAttribute가 제대로 동작해주었기 때문에 ITest 인터페이스로 할당을 하도록 했지만 실질적으로는 Test 클래스가 할당된 것이다. 그러나 CoClassAttribute로 지정된 형식이 인스턴스 생성을 원하는 코드의 입장에서 보호된 형식인 경우 생성자 호출을 할 수 없다.
Creative Commons License
Creative Commons License
남정현 이 작성.

당신의 의견을 작성해 주세요.

[로그인][오픈아이디란?]
오픈아이디로만 댓글을 남길 수 있습니다

1. IDispatch 인터페이스에 대한 COM Smart Pointer 만드는 법

[CODE]
_com_ptr_t<_com_IIID<IDispatch, &__uuidof(IDispatch)> > oDispatch1(/* 이곳에 Interface Pointer를 인수로 지정한다. */);
[/CODE]

2. 이것을 매크로 구문으로 만든다면...

[CODE]
#ifndef COM_PTR
#define COM_PTR(x) _com_ptr_t<_com_IIID<x, &__uuidof(x)> >
#endif // COM_PTR

COM_PTR(IDispatch) oDispatch1(/* 이곳에 Interface Pointer를 인수로 지정한다. */);
[/CODE]

* 필요한 헤더 파일: comip.h

Creative Commons License
Creative Commons License
남정현 이 작성.

당신의 의견을 작성해 주세요.

[로그인][오픈아이디란?]
오픈아이디로만 댓글을 남길 수 있습니다