8 std::ostringstream oss;
9 oss << message <<
": " << ce.ErrorMessage();
18 V_VT(v) = VT_ARRAY | v_type;
19 SAFEARRAYBOUND* sab =
new SAFEARRAYBOUND[ndims];
25 for(i=0; i<ndims; i++)
28 sab[i].cElements = dims_array[ndims-i-1];
30 V_UNION(v,parray) = SafeArrayCreate(v_type, ndims, sab);
32 if (V_UNION(v,parray) == NULL)
45 hr = SafeArrayGetVartype(V_UNION(v,parray), &vtt);
50 hr = SafeArrayAccessData(V_UNION(v,parray), values);
51 if ( FAILED(hr) || (*values == NULL) )
86 HRESULT hr = SafeArrayUnaccessData(V_UNION(v,parray));
97 if (!(V_VT(v) & VT_ARRAY))
101 SAFEARRAY* psa = V_UNION(v,parray);
106 int ndims = SafeArrayGetDim(psa);
111 long lbounds, ubounds;
114 for(i=0; i<ndims; i++)
116 lbounds = ubounds = 0;
117 SafeArrayGetLBound(psa, i+1, &lbounds);
118 SafeArrayGetUBound(psa, i+1, &ubounds);
119 len *= (ubounds - lbounds + 1);
128 if (!(V_VT(v) & VT_ARRAY))
132 SAFEARRAY* psa = V_UNION(v,parray);
137 ndims = SafeArrayGetDim(psa);
138 long lbounds, ubounds;
139 for(
int i=0; i<ndims; i++)
141 lbounds = ubounds = 0;
142 SafeArrayGetLBound(psa, i+1, &lbounds);
143 SafeArrayGetUBound(psa, i+1, &ubounds);
144 dims_array[i] = ubounds - lbounds + 1;
149 template <
typename T>
158 int n = the_array.size();
160 BSTR* v_array = NULL;
162 for(
int i=0; i<n; ++i)
164 CComBSTR bstr_wrapper(the_array[i].c_str());
165 v_array[i] = bstr_wrapper.Detach();
172 template <const VARTYPE vt>
190 template <
typename T>
193 VARTYPE vt_type = CVarTypeInfo<T>::VT;
197 for(
int i=0; i<n; ++i)
199 v_array[i] = the_array[i];
215 static void GenieVariableToVariant(GenieVariable& gv, VARIANT* v,
const char* opt)
218 static OOP gxcominterface = typeNameToOOP(
"GXCominterface");
225 case GenieIntegerType:
227 V_UNION(v,lVal) = (GenieInteger)gv;
232 V_UNION(v,dblVal) = (GenieReal)gv;
235 case GenieStringType:
237 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
238 (GenieString)gv, -1, olestr_buffer, MAX_OLE_SIZE);
239 V_UNION(v,bstrVal) = SysAllocString(olestr_buffer);
242 case GenieWorkspaceType:
244 GenieWorkspace& gw = (GenieWorkspace&)gv;
245 if (gw.getClass() == gxcominterface)
247 GenieIntegerArray gia = gw(
"value");
248 l = (GenieInteger)gw(
"type");
253 memcpy(&(V_UNION(v,punkVal)), (g_integer*)gia,
sizeof(IUnknown*));
257 memcpy(&(V_UNION(v,pdispVal)), (g_integer*)gia,
sizeof(IDispatch*));
261 gerr <<
"DCOM: GenieVariableToVariant(workspace, unknown type) " << l << std::endl;
267 gerr <<
"DCOM: Unsupported workspace type" << std::endl;
272 case GenieWorkspaceArrayType:
274 GenieWorkspaceArray& gwa = (GenieWorkspaceArray&)gv;
276 tmp = (VARIANT*)safeArraySetup(gwa, v, VT_VARIANT);
279 gerr <<
"DCOM: error" << std::endl;
282 for(i=0; i<gwa.length(); i++)
284 GenieWorkspace gw = gwa[i];
285 GenieVariable gv = gw(
"value");
286 GenieVariableToVariant(gv, &tmp[i],
"");
288 hr = SafeArrayUnaccessData(V_UNION(v,parray));
291 gerr <<
"DCOM: failed" << std::endl;
297 case GenieIntegerArrayType:
299 GenieIntegerArray& gia = (GenieIntegerArray&)gv;
301 vt_type = (*opt ==
'A' ? VT_I4 : VT_VARIANT);
302 tmp = (VARIANT*)safeArraySetup(gia, v, vt_type);
305 gerr <<
"DCOM: error" << std::endl;
308 if (vt_type == VT_VARIANT)
310 for(i=0; i<gia.length(); i++)
312 V_VT(&tmp[i]) = VT_I4;
313 V_UNION(&tmp[i],lVal) = gia[i];
318 memcpy(tmp, (g_integer*)gia, gia.length() * 4);
320 hr = SafeArrayUnaccessData(V_UNION(v,parray));
323 gerr <<
"DCOM: failed" << std::endl;
328 case GenieRealArrayType:
330 GenieRealArray& gra = (GenieRealArray&)gv;
332 vt_type = (*opt ==
'A' ? VT_R8 : VT_VARIANT);
333 tmp = (VARIANT*)safeArraySetup(gra, v, vt_type);
336 gerr <<
"DCOM: error" << std::endl;
339 if (vt_type == VT_VARIANT)
341 for(i=0; i<gra.length(); i++)
343 V_VT(&tmp[i]) = VT_R8;
344 V_UNION(&tmp[i],dblVal) = gra[i];
349 memcpy(tmp, (g_real*)gra, gra.length() * 8);
351 hr = SafeArrayUnaccessData(V_UNION(v,parray));
354 gerr <<
"DCOM: failed" << std::endl;
359 case GenieStringArrayType:
361 GenieStringArray& gsa = (GenieStringArray&)gv;
363 vt_type = (*opt ==
'A' ? VT_BSTR : VT_VARIANT);
364 tmp = (VARIANT*)safeArraySetup(gsa, v, vt_type);
367 gerr <<
"DCOM: error" << std::endl;
370 for(i=0; i<gsa.length(); i++)
372 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
373 (GenieString)gsa[i], -1, olestr_buffer,
375 if (vt_type == VT_VARIANT)
377 V_VT(&tmp[i]) = VT_BSTR;
378 V_UNION(&tmp[i],bstrVal) = SysAllocString(olestr_buffer);
382 ((BSTR*)tmp)[i] = SysAllocString(olestr_buffer);
385 hr = SafeArrayUnaccessData(V_UNION(v,parray));
388 gerr <<
"DCOM: failed" << std::endl;
394 gerr <<
"DCOM: GenieVariableToVariant(unknown type) " << std::endl;
399 static void VariantToGenieVariable(VARIANT* v, GenieVariable& gv);
401 static int getVariantArrayLength(VARIANT* v)
403 if (!(V_VT(v) & VT_ARRAY))
407 SAFEARRAY* psa = V_UNION(v,parray);
412 int ndims = SafeArrayGetDim(psa);
413 long lbounds, ubounds;
416 for(i=0; i<ndims; i++)
418 lbounds = ubounds = 0;
419 SafeArrayGetLBound(psa, i+1, &lbounds);
420 SafeArrayGetUBound(psa, i+1, &ubounds);
421 len *= (ubounds - lbounds + 1);
426 static void VariantToGenieVariableArray(VARIANT* v, GenieVariable& gv)
428 SAFEARRAY* psa = V_UNION(v,parray);
431 gerr <<
"DCOM: VariantToGenieVariableArray error" << std::endl;
434 int ndims = SafeArrayGetDim(psa);
435 long *lbounds =
new long[ndims];
436 long *ubounds =
new long[ndims];
437 int* dims_array =
new int[ndims];
441 for(i=0; i<ndims; i++)
443 SafeArrayGetLBound(psa, i+1, lbounds+i);
444 SafeArrayGetUBound(psa, i+1, ubounds+i);
445 dims_array[ndims - i - 1] = ubounds[i] - lbounds[i] + 1;
446 len *= dims_array[ndims - i - 1];
450 vvt = (V_VT(v) & ~VT_ARRAY);
453 hr = SafeArrayGetVartype(psa, &vt);
454 if ( FAILED(hr) || (vt != vvt) )
456 gerr <<
"DCOM: VariantToGenieVariableArray - possible data type mismatch?" << std::endl;
462 hr = SafeArrayAccessData(psa, &pdata);
463 if ( FAILED(hr) || (pdata == NULL) )
465 gerr <<
"DCOM: error" << std::endl;
468 GenieIntegerArray* gia;
470 GenieStringArray *gsa;
471 GenieWorkspaceArray *gwa;
473 if (vt == VT_VARIANT)
476 gwa =
new GenieWorkspaceArray(len);
479 pv = (VARIANT*)pdata + i;
481 VariantToGenieVariable(pv, gvv);
483 gw(
"value", gvv.value());
486 gv.newType(GenieWorkspaceArrayType, gwa->value());
502 gia =
new GenieIntegerArray((
long*)pdata, dims_array, ndims);
503 gv.newType(GenieIntegerArrayType, gia->value());
509 gia =
new GenieIntegerArray((
int*)pdata, dims_array, ndims);
510 gv.newType(GenieIntegerArrayType, gia->value());
514 gra =
new GenieRealArray((
float*)pdata, dims_array, ndims);
515 gv.newType(GenieRealArrayType, gra->value());
519 gra =
new GenieRealArray((
double*)pdata, dims_array, ndims);
520 gv.newType(GenieRealArrayType, gra->value());
524 gsa =
new GenieStringArray(dims_array, ndims);
528 pBstr = (BSTR*)pdata + i;
529 l = SysStringLen(*pBstr);
530 j = WideCharToMultiByte(CP_ACP, 0, *pBstr, l,
531 str_buffer, MAX_OLE_SIZE, NULL, NULL);
532 str_buffer[j] =
'\0';
533 (*gsa)(i, str_buffer);
535 gv.newType(GenieStringArrayType, gsa->value());
539 gerr <<
"VariantToGenieVariableArray(unknown type) " << vt << std::endl;
543 SafeArrayUnaccessData(psa);
549 static void VariantToGenieVariable(VARIANT* v, GenieVariable& gv)
555 VariantInit(&temp_v);
556 GenieIntegerArray gia(2);
557 if (V_VT(v) & VT_ARRAY)
560 VariantToGenieVariableArray(v, gv);
578 VariantChangeType(&temp_v, v, 0, VT_I4);
579 gi = V_UNION(&temp_v,lVal);
580 gv.newType(GenieIntegerType, gi);
587 gi = (V_UNION(v,boolVal) != 0 ? 1 : 0);
588 gv.newType(GenieIntegerType, gi);
596 VariantChangeType(&temp_v, v, 0, VT_R8);
597 gr = V_UNION(&temp_v,dblVal);
598 gv.newType(GenieRealType, gr);
604 l = SysStringLen(V_UNION(v,bstrVal));
605 i = WideCharToMultiByte(CP_ACP, 0, V_UNION(v,bstrVal), l,
606 str_buffer, MAX_OLE_SIZE, NULL, NULL);
607 str_buffer[i] =
'\0';
609 gv.newType(GenieStringType, gs);
615 GenieWorkspace gw(
"GXCominterface");
616 gia((g_integer*)&(V_UNION(v,punkVal)),
sizeof(IUnknown*) /
sizeof(g_integer));
617 gw(
"name",
"IUnknown");
618 gw(
"type", VT_UNKNOWN);
620 gv.newType(GenieWorkspaceType, gw);
621 iunk_list.push(iunk_item(V_UNION(v,punkVal)));
627 GenieWorkspace gw(
"GXCominterface");
628 gia((g_integer*)&(V_UNION(v,pdispVal)),
sizeof(IDispatch*) /
sizeof(g_integer));
629 gw(
"name",
"IDispatch");
630 gw(
"type", VT_DISPATCH);
632 gv.newType(GenieWorkspaceType, gw);
633 idisp_list.push(idisp_item(V_UNION(v,pdispVal), 0));
639 gerr <<
"DCOM: VariantToGenieVariable(unknown type) " << V_VT(v) << std::endl;
646 static void DCOMCleanupVariant(VARIANT* v)
653 vt = (vvt & ~VT_ARRAY);
654 if ( (vvt & VT_ARRAY) && (vt == VT_VARIANT) )
656 SAFEARRAY* psa = V_UNION(v,parray);
657 len = getVariantArrayLength(v);
658 hr = SafeArrayAccessData(psa, (
void**)&pv);
659 if ( SUCCEEDED(hr) && (pv != NULL) )
663 DCOMCleanupVariant(pv + i);
665 SafeArrayUnaccessData(psa);
694 gerr <<
"DCOM: CleanupVariant(unknown type) " << V_VT(v)<<
"/" << vt << std::endl;
int allocateArrayVariant(VARIANT *v, VARTYPE v_type, int *dims_array, int ndims)
static int accessArrayVariant(VARIANT *v, void **values, VARTYPE vt)
int arrayVariantLength(VARIANT *v)
int arrayVariantDimensions(VARIANT *v, int dims_array[], int &ndims)
int unaccessArrayVariant(VARIANT *v)
static std::string com_message(const std::string &message, HRESULT hr)
int makeVariantFromArray(VARIANT *v, const std::vector< T > &the_array)