***************************************************
A CODER 0925-ban irta  :
***************************************************
>Olyan progamot szeretnek irni ami felhiv egy adott telefonszamot es a
>hivott szamitogeppel kommunikal, csak nem tudom, hogy fogjak hozza, s
>ehhez szeretnem a segitsegetek kerni.
>(pl: file-t szeretnek kuldeni, s onnan file-t fogadni)
PcAnywhere nevu prg. A felhivott szamitogepen bongeszhetsz is a
megfelelo jelszo megadasa utan.
Symantec termek.
Minden jot,
               Ricsi
               mailto: 
               Ifjusagi Unio: http://w3.swi.hu/xifu
Ui.: Ment maganba is
Szegeny ember vizzel kavics...
  | 
	
	
Csao!
Ha nem zavarok, egy hosszu pelda, es talan nehany bugot eszrevesz
benne egy igazi szakerto ;)
Eppen mostanában szenvedtem olyanokkal, hogy egy Automatizált szerver
visszalok egy tombot, es abbol kell kinyerni az infot - igaz, Borland
C++ Builderben, de ez talan nem olyan nagy baj a kerdezonek.
Az a baj, hogy erre a szerverek tobbfajta megoldast hasznalnak pl:
  - visszaad egy variantot, amiben pl BSTR-ekbol keszitett tomb van
  - visszaad egy variantot, amiben Variant tomb van, azokban az ertekek
A kovetkezo egy pelda, a BCB alatt mukodott, ami egy olyan tombot
dolgoz fel, amiben variantok vannak, azokban pedig stringek.
FOPROGRAM.CPP:
   //fuggv hivas, tomb atszivasa 1 Borland variantba
   TVariant arrvar;
   OBJ.GET_ARRAYFUNCTION(&arrvar);
   //visszaadott ertek ellenorzese: VT_ARRAY | VT_VARIANT -> variant tomb
   if (V_VT(&arrvar) != (VT_ARRAY | VT_VARIANT))
      return 0;
   //uj safearray letrehozasa es ertekek atmasolasa
   SAFEARRAY* Arr = (SAFEARRAY*)(arrvar);
   //helper class segitsegevel egyszerubb kezeles.
   TSafeArrayT<Variant, VT_VARIANT, 1> VclArr(Arr);
   //tomb feldolgozasa
   for(int i=0; i<VclArr.BoundsLength[0]; i++)
   {
      Variant v = VclArr[i];
      AnsiString Devname = AnsiString(v);
      ...
   }
Sajnos ez csak BCB4-ben mukodott ilyen egyszeruen(?), a BCB5-ben a
GET_ARRAYFUNCTION TLB-bol generalt kodot is at kellett irni. Ideirom,
talan nem hasznontalan.
Itt az a> jelu sorok automatikusan generaltak, de sajnos itt mar at
kell masolni a tomb egesz tartalmat egy teljesen uj tombbe.
SERVER_TLB.H:
a> template <class T> HRESULT __fastcall IDeviceAccessDispT<T>:: 
a> GET_ARRAYFUNCTION(TVariant* List/*[out,retval]*/)
a> {
a>   _TDispID _dispid(*this, OLETEXT("GET_ARRAYFUNCTION"), DISPID(39));
a>   TAutoArgs<0> _args;
a> 
a>   HRESULT hr = OlePropertyGet(_dispid, _args);
a>   if( SUCCEEDED(hr) )
a>   {
     VARIANT* V = _args.GetRetVariant(); //visszaadott variant
     if( V_ARRAY(V) ) //ha ez tenyleg tomb
     {
        //ez csak kiveszi a variantbol a tomb pointert, nincs copy
        SAFEARRAY *src = V_ARRAY(V); 
        // Get array bounds.
        static long cElements, lLBound, lUBound;
        SafeArrayGetLBound(src, 1, &lLBound);
        SafeArrayGetUBound(src, 1, &lUBound);
        cElements = lUBound-lLBound+1;
        //Create new dest array.
        SAFEARRAY *dest=0;
        SAFEARRAYBOUND bounds = {cElements, 0};
        dest = ::SafeArrayCreate(VT_VARIANT, 1, &bounds);
        //Lock and copy variants from src to dest.
        VARIANT *DestArray, *SrcArray;
        ::SafeArrayAccessData(src,  (void **)&SrcArray);
        ::SafeArrayAccessData(dest, (void **)&DestArray);
        for(int i=0; i<cElements; i++)
           DestArray[i] = SrcArray[i]; //copy variant.
        //Unlock src and dest.
        ::SafeArrayUnaccessData(src);
        ::SafeArrayUnaccessData(dest);
        //Itt a kimeno variantba attoltjuk az adatokat, ezt fogja megkapni a hi
vo
        List->SetSAFEARRAY(dest);
     }
     else
        *List = *V; //sima variant masolas, ez tomboknel elszall BCB5-ben!!!
a>   }
a>   return hr;
a> }
Ennek a kezi modszernek meg egy hibaja van: manualisan kell
elpusztitani szegeny variant tombot, miutan mar nincs ra szukseg,
kulonben memoriaszivargas lep fel:
FOPROGRAM.CPP:
   ...
   //tomb feldolgozasa
   for(int i=0; i<VclArr.BoundsLength[0]; i++)
   {
      Variant v = VclArr[i];
      AnsiString Devname = AnsiString(v);
      ...
   }
   SafeArrayDestroyData(V_ARRAY(&arrvar));
   SafeArrayDestroy(V_ARRAY(&arrvar));
-- 
Józsi
 
 |