본문으로 바로가기

SAFEARRAY를 사용한 VARIANT ARRAY(배열) 다루기(VC++)

category 개발언어/c++ 2016. 9. 2. 16:45

VB의 경우 VARIANT관련해서 조작은 아주 간편하다. VB만 사용하는 개발자라면 VARIANT  Type의 자료형이 존재한다는 사실조차 의식하지 못할 정도이다.

MFC (VC++)에서 VARIANT 와 VARIANT ARRAY(배열)를 사용하는 방법은 다소 까다롭다. 
물론 내가 처음 VC++을 접할 때 OLE,COM등에 대해 별로 관심이 깊지 않았던 탓에 VARIANT를 다룰 기회가 없었던 이유도 있지만, 사용의 필요성을 느끼지 못했던 것도 사실이다.

그런데 어느 순간부터 사용하는 개발툴이 하나 둘 늘어나기 시작했다.
현업에서 일을 하다 보면 내가 사용하지 않았던 개발언어를 다루어야 할 경우가 생긴다. 다른 소스를 참조해야 하거나 여러 부서 또는 다른 회사와 공동작업을 해야 하는 경우도 있다.
이럴 때 dll,ATL,COM 을 사용하면 개발언어간의 장벽 사이에서 유연하게 재사용 가능한 코드를 작성할 수 있다.  그런데 라이브러리에 서 작성한 함수에 인자로 전달하는 변수형의 호환성이 항상 문제가 된다. VARIANT는 다른 종류의 개발 언어 사이에서 서로호환 되는 변수형이다. 

또한 VARIANT ARRAY(배열)을 다루는 함수는 SAFEARRAY임을 잘 기억하자.

아래의 예는 복합적인 변수형식을 VARINT Type 포인터로 넘겨서 처리 하는 방법 이다.

//thread에서 처리 가능하도록 Void Type의 자료넘김
 
DWORD  Function(LPVOID lpParam)
{    
    LPMITEM p_item=(LPMITEM)lpParam;//파라메터로 넘기기 위해 정의된 구조체
    p_item->b_Thread_Run=TRUE;
   //내가만든 ATL Class를 인자로 넘겨 받는다
    CComObject* p_Simul =(CComObject*)p_item->p_sim;
    p_Simul->Test((int*)&b_OK);  //ATL Class에 정의된 함수 호출   
    ////////////////////////////////////////
   // 함수의 실행 결과를 다중배열 복합 Data로 받기 위한 Variant Point
    VariantInit(&p_item->v_Rtn);   // Variant 초기화
    V_VT(&p_item->v_Rtn) = (VT_VARIANT|VT_ARRAY);//Variant Type의 배열선언    
   //2개의 Variant 배열생성    
   V_ARRAY(&p_item->v_Rtn) = SafeArrayCreateVector(VT_VARIANT, 0, 2);
    ////////////////////////////////////////
    VARIANT *p_var=NULL,*pv_child=NULL;
    VARIANT t_var;
    //Variant의 Array를 가져오기 및 Lock 해제 
    SafeArrayAccessData(p_item->v_Rtn.parray, reinterpret_cast(&p_var)); 
    ///첫 번째 배열에 2개의 Variant 배열을 할당하여 만들기
    V_VT(&p_var[0]) = (VT_VARIANT|VT_ARRAY);    
    V_ARRAY(&p_var[0]) = SafeArrayCreateVector(VT_VARIANT, 0, 2);
    //할당된 배열에서 Variant Point가져오기 
    SafeArrayAccessData(p_var[0].parray, reinterpret_cast(&pv_child)); 
   //문자열 형태의 변수 넣기    
    t_var=_variant_t(" name");="" variantcopy(&pv_child[0],&t_var);="" 넘겨진="" 클래스의="" 멤버변수의="" 값을="" 가져오기="" t_var="_variant_t(p_Simul-">id_Name);
    VariantCopy(&pv_child[1],&t_var);        
    //첫 번째 배열에 Variant 배열을 넣고 Lock실행      
    SafeArrayUnaccessData(p_var[0].parray);
    
    ///////////////////////////////////////////
    /// 첫 번째 배열과 같은 방법으로 두 번째 배열도 값을 할당
    V_VT(&p_var[1]) = (VT_VARIANT|VT_ARRAY);    
    V_ARRAY(&p_var[1]) = SafeArrayCreateVector(VT_VARIANT, 0, 2); 
    SafeArrayAccessData(p_var[1].parray, reinterpret_cast(&pv_child)); 
    t_var=_variant_t("RESULT");
    VariantCopy(&pv_child[0],&t_var);
    t_var=_variant_t(b_OK);
    VariantCopy(&pv_child[1],&t_var);
    SafeArrayUnaccessData(p_var[1].parray);
    ///////////////////////////////////////////
   //최상위 배열 Lock    
    SafeArrayUnaccessData(p_item->v_Rtn.parray);
    VariantClear(&t_var);
    VariantClear(p_var);
    VariantClear(pv_child);
    p_item->b_Thread_Run=FALSE;
    p_item=NULL;
    p_Simul=NULL;    return 0;
}

여기서 주목 해야 할 부분은 SafeArrayAccessData에서 Variant Point로 접근하는 부분과 SafeArrayUnaccessData를 사용해서 Lock을 시키는 부분이다.


'개발언어 > c++' 카테고리의 다른 글

MFC IP얻기  (1) 2016.10.03
고속연속평균-실시간평균  (0) 2016.09.16
[MFC]NI CWGraph 사용예제  (0) 2016.08.02
[MFC] NI CWGraph 사용 잘 하는 법  (0) 2016.08.02
MDI(Multi Document Interface)로 개발하기(완료)  (0) 2016.07.26