본문 바로가기

프로그래밍

[COM] SafeArray 처리

#include <iostream>
using namespace std;

#include <windows.h>
#include <comdef.h>

void ComCall(VARIANT* pRetVal)
{
enum { ARR_SIZE = 5 };
VariantInit(pRetVal);

short ia[ARR_SIZE] = {5, 6, 7, 8, 9 }; //넘기고자 하는 배열

SAFEARRAYBOUND sab = { ARR_SIZE, 0 };
SAFEARRAY* pSa = SafeArrayCreate(VT_VARIANT, 1, &sab);

_variant_t* _p;
// 만든 SA배열에 포인터를 연결시킴
SafeArrayAccessData(pSa, reinterpret_cast<void**>(&_p));

for (long i = 0; i < ARR_SIZE; i++) {
_p[i] = (long)ia[i];
}

SafeArrayUnaccessData(pSa);

pRetVal->vt = VT_VARIANT | VT_ARRAY;
pRetVal->parray = pSa;

// 위에 두줄을 이렇게 해도 됨
//_variant_t var;
//var.vt = VT_VARIANT | VT_ARRAY;
//var.parray = pSa;
// 꼭 Detach로 넘겨야함 그냥 대입하면 var변수가 메모리가 헤제되버림
// 그럼 *pRetVal 도 같이 메모리 해제되어서 ....
//*pRetVal = var.Detach();
}

int main()
{
_variant_t var;
ComCall(&var);

SAFEARRAY* pSa;

if (var.vt & VT_ARRAY) {
if (var.vt & VT_BYREF)
pSa = *var.pparray;
else
pSa = var.parray;
}
else {
cout << "SafeArray가 아님" << endl;
reutrn 0;
}

long lUBound = 0;
SafeArrayGetUBound(pSa, 1, &lUBound);

_variant_t* _p;
SafeArrayAccessData(pSa, reinterpret_cast<void**>(&_p));

for (int i = 0; i <= lUBound; i++) {
cout << static_cast<long>(_p[i]) << endl;
}

SafeArrayUnaccessData(pSa);

cout << "== END ==" << endl;
cin.get();

return 0;
}