Flylib.com

Books Software

 
 
 

Essential COM - page 32

IDL. IDL , . 2.6 , IDL, , Java Visual Basic. . "" , ÷ , - .

ß

IDL

Microsoft C++

Visual Basic

Microsoft Java

boolean

unsigned char

unsupported

char

byte

unsigned char

unsupported

char

small

char

unsupported

char

short

short

Integer

short

long

long

Long

int

hyper

_int64

unsupported

long

float

float

Single

float

double

double

Double

double

char

unsigned char

unsupported

char

wchar_t

wchar_t

Integer

short

enum

enum

Enum

int

Interface Pointer

Interface Pointer

Interface Ref.

Interface Ref.

ø

VARIANT

VARIANT

Variant

ms.com.Variant

BSTR

BSTR

String

java.lang.String

VARIANT_BOOL

short [-1/0]

Boolean [True/False]

boolean [true/false]


. 2.6.

OLECHAR . Windows NT, Windows 95, Win32s Solaris OLECHAR - typedef wchar_t . . Win32 wchar_t 16- Unicode 1 . IDL , ÷ ÷ , , IDL [string] , ÷ ÷, ÷ - ø :

HRESULT Method([in, string] const OLECHAR *pwsz);

, OLECHAR , OLESTR , L , , ÷ wchar_t . , OLECHAR :

const OLECHAR *pwsz = OLESTR("Hello");

Win32 Solaris

const wchar_t *pwsz = L"Hello";

÷, .

÷ wchar_t ÷ char , ÷ :

size_t mbstowcs(wchar_t *pwsz, const char *psz, int cch); 
size_t wcstombs(char *psz, const wchar_t *pwsz, int cch);

÷ ÷ - strncpy , ÷ , ÷ ÷ ÷ ø . , , OLECHAR , , char :

class BigDog : public ILabrador { 
    char m_szName[1024] ; 
  public: 
    STDMETHODIMP SetName(/* [in,string]*/ const OLECHAR *pwsz) { 
        HRESULT hr = S_OK; 
        size_t cb = wcstombs(m_szName, pwsz, 1024); 
        // check for buffer overflow or bad conversion 
        // проверяем переполнение буфера или неверное преобразование 
        if (cb == sizeof(m_szName)  cb == (size_t)-1) { 
            m_szName[0] = 0;
            hr = E_INVALIDARG; 
        } 
        return hr; 
    } 
};

, , ÷ ÷ . ( ÷ ÷) ÷ - OLECHAR TCHAR Win32. OLECHAR char wchar_t , :

class BigDog : public ILabrador {
    TCHAR m_szName[1024]; 
    // note TCHAR-based string 
    // отметим строку типа TCHAR 
  public: 
    STDMETHODIMP SetName( /*[in,string]*/ const OLECHAR *pwsz) { 
        HRESULT hr = S_OK;
        #ifdef UNICODE 
        // Unicode build (TCHAR == wchar_t) 
        // конструкция Unicode (TCHAR == wchar_t) 
        wcsncpy(m_szName, pwsz, 1024); 
        // check for buffer overflow 
        // проверка на переполнение буфера 
        if (m_szName[1023] != 0) { 
            m_szName[0] = 0; 
            hr = E_INVALIDARG; 
        }  
        #else 
        // Non-Unicode build (TCHAR == char) 
        // не является конструкцией Unicode (TCHAR == char) 
        size_t cb = wcstombs(m_szName, pwsz, 1024); 
        // check for buffer overflow or bad conversion 
        // проверка переполнения буфера или ошибки преобразования 
        if (cb == sizeof(m_szName)  cb == (size_t)-1) { 
            m_szName[0] =0;
            hr = E_INVALIDARG;
        }
        #endif 
        return hr; 
    } 
};

÷ , OLECHAR TCHAR ÷ . , , Win32.

C++ , . ÷ ustring.h ÷ , ÷ ÷ , string.h . , strncpy ÷ , , ( wchar_t char ):

// from ustring.h (book-specific header) 
// из ustring.h (заголовок, специфический для данной книги) 
inline bool ustrncpy(char *p1, const wchar_t *p2, size_t c)
{ 
    size_t cb = wcstombs(p1, p2, c); 
    return cb != c && cb != (size_t)-1; 
}; 

inline bool ustrncpy(wchar_t *p1, const wchar_t *p2, size_t c)
{ 
    wcsncpy(p1, p2, c); 
    return p1[c - 1] == 0; 
};

inline bool ustrncpy(char *p1, const char *p2, size_t c) 
{ 
    strncpy(p1, p2, c); 
    return p1[c - 1] == 0; 
}; 

inline bool ustrncpy(wchar_t *p1, const char *p2, size_t c)
{ 
    size_t cch = mbstowcs(p1, p2, c); 
    return cch != c && cch != (size_t)-1; 
}

, ÷ ÷ ustrncpy , ÷ , . (inline) , . ÷ :

class BigDog : public ILabrador { 
    TCHAR m_szName[1024]; 
      // note TCHAR-based string 
      // отметим строку типа TCHAR
  public: 
    STDMETHODIMP SetName(/* [in,string] */ const OLECHAR *pwsz) {
        HRESULT hr = S_OK; 
        // use book-specific overloaded ustrncpy to copy or convert 
        // используем для копирования и преобразования 
        // перегруженную функцию ustrncpy, специфическую для данной книги
        if (!ustrncpy(m_szName, pwsz, 1024)) { 
            m_szName[0] = 0; 
            hr = E_INVALIDARG; 
        } 
        return hr; 
    } 
};

strlen , strcpy strcat ÷ ÷ ustring.h .

÷ , ø, ÷ ÷ø ÷ , ø . ÷ , API- Win32, ÷ . , ÷ IID :

HRESULT IIDFromHWND(HWND hwnd, IID& riid) 
{ 
    TCHAR szEditText[1024]; 
        // call a TCHAR-based Win32 routine 
        // вызываем TCHAR-процедуру Win32 
    GetWindowText(hwnd, szEditText, 1024); 
        // call an OLECHAR-based СОМ routine 
        // вызываем OLECHAR-процедуру СОМ 
    return IIDFromString(szEditText, &riid); 
}

, ÷ - UNICODE; ÷, TCHAR OLECHAR wchar_t . Win32 API, Unicode, TCHAR char, IIDFromString . × ø , :

HRESULT IIDFromHWND(HWND hwnd, IID& riid) 
{ 
    TCHAR szEditText[1024]; 
    GetWindowText(hwnd, szEditText, 1024); 
    #ifdef UNICODE 
    return IIDFromString(szEditText, &riid); 
    #else 
    OLECHAR wszEditText[l024]; 
    ustrncpy(wszEditText, szEditText, 1024); 
    return IIDFromString(wszEditText, &riid); 
    #endif
}

, ÷ , . , ÷ ( shim ) , ÷ . ÷ , ÷ ÷: const char * const wchar_t * . ÷ , , . ÷ . ÷ ustring.h ÷ : _U _UNCC . ÷ ; , ÷ const 2 ( IIDFromString ). ÷ ÷ :

HRESULT IIDFromHWND(HWND hwnd, IID& riid) 
{
    TCHAR szEditText[1024]; 
    GetWindowText(hwnd, szEditText, 1024); 
        // use _UNCC shim class to convert if necessary 
        // используем для преобразования промежуточный класс _UNCC, 
        // если необходимо 
    return IIDFromString(_UNCC(szEditText), &riid);
}

, ÷ . Win32 Unicode, _UNCC ÷ . Win32, Unicode, _UNCC Unicode. _UNCC , 3 .

, , - BSTR . BSTR , Visual Basic Java. BSTR OLECHAR - ( length-prefix ) ÷ . ÷ , (÷ ø ) ÷ ÷, ø . 2.7 BSTR "Hi" . × BSTR , BSTR , . API- BSTR :

. 2.7. "hi" bstr

// from oleauto.h 
// allocate and initialize a BSTR 
// выделяем память и инициализируем строку BSTR 

BSTR SysAllocString(const OLECHAR *psz); 
BSTR SysAllocStringLen(const OLECHAR *psz, UINT cch); 

// reallocate and initialize a BSTR 
// повторно выделяем память и инициализируем BSTR 
INT SysReAllocString(BSTR *pbstr, const OLECHAR *psz); 
INT SysReAllocStringLen(BSTR *pbstr, const OLECHAR * psz, UINT cch); 

// free a BSTR 
// освобождаем BSTR 
void SysFreeString(BSTR bstr); 

// peek at length-prefix as characters or bytes 
// считываем префикс длины как число символов или байт 
UINT SysStringLen(BSTR bstr);
UINT SysStringByteLen(BSTR bstr);

÷ [in] , ÷ SysAllocString , ÷ , ÷ SysFreeString , ÷ . :

HRESULT SetString([in] BSTR bstr);

, OLECHAR , , ÷ BSTR , :

// convert raw OLECHAR string to a BSTR 
 // преобразовываем "сырую" строку OLECHAR в строку BSTR 
BSTR bstr = SysAllocString(OLESTR("Hello")); 
 // invoke method 
 // вызываем метод 
HRESULT hr = p->SetString(bstr); 
 // free BSTR 
 // освобождаем BSTR 
SysFreeString(bstr);

÷ BSTR , _UBSTR , ÷ ÷ ustring.h :

// from ustring.h (book-specific header file)
// из ustring.h (специфический для данной книги заголовочный файл)
class _UBSTR { 
    BSTR m_bstr; 
  public: 
    _UBSTR(const char *psz) : m_bstr(SysAllocStringLen(0, strlen(psz))) { 
        mbstowcs(m_bstr, psz, INT_MAX); 
    } 
    _UBSTR(const wchar_t *pwsz) : m_bstr(SysAllocString(pwsz)) { } 
    operator BSTR (void) const { return m_bstr; } 
    ~_UBSTR(void) { SysFreeString(m_bstr); } 
};

÷ ÷ ÷ :

// invoke method 
// вызываем метод 
HRESULT hr = p->SetString(_UBSTR(OLESTR("Hello")));

, ÷ ÷ UBSTR char wchar_t .

÷ ÷ [out] SysAllocString , ÷ . SysFreeString . :

HRESULT GetString([out, retval] BSTR *pbstr);

BSTR - :

STDMETHODIMP MyClass::GetString(BSTR *pbstr) 
{ 
    *pbstr = SysAllocString(OLESTR("Coodbye!")) ; 
    return S_OK; 
}

, :

extern OLECHAR g_wsz[]; 
BSTR bstr = 0; 
HRESULT hr = p->GetString(&bstr); 
if (SUCCEEDED(hr)) { 
    wcscpy(g_wsz, bstr); 
    SysFreeString(bstr); 
}

BSTR . ÷ BSTR , ÷ . ÷, ÷ . wcscpy :

wcscpy(g_wsz, bstr);

:

wcscpy (g_wsz, bstr ? bstr : OLESTR(""));

BSTR ÷ ustring.h :

intline OLECHAR *SAFEBSTR(BSTR b)
{ 
    return b ? b : OLESTR(""); 
}

ø ÷ BSTR ÷ , .

, . 2.6, . IDL ÷ (tag namespace). ÷, ÷ ø IDL- ( typedef ):

typedef struct tagCOLOR { 
    double red; 
    double green; 
    double blue; 
} COLOR; 

HRESULT SetColor([in] const COLOR *pColor);

÷ struct :

struct COLOR { 
    double red;
    double green; 
    double blue; 
}; 

HRESULT SetColor([in] const struct COLOR *pColor);

÷. , ø, Visual Basic, Java. , ø , Visual Basic , , , .

IDL ( unions ). ÷ ÷ IDL , ÷ ( discriminator ), , ÷ . ( integral type ) ÷ , ÷ . , ÷ ( nonencapsulated ):

union NUMBER { 
 [case(1)] long i;
 [case(2)] float f; 
};

[case] ÷ . ÷ , [switch_is] :

HRESULT Add([in, switch_is(t)] union NUMBER *pn, [in] short t);

÷ , ( aggregate type ) , ÷ ( discriminated union ):

struct UNUMBER { 
    short t; 
    [switch_is(t)] union VALUE { 
        [case(1)] long i;
        [case(2)] float f; 
    }; 
};

Visual Basic ÷ . VARIANT 4 , IDL. ÷ :

VT_EMPTY       nothing 
VT_NULL        SQL style Null 
VT_I2          short 
VT_I4          long 
VT_R4          float 
VT_R8          double 
VT_CY          CY (64-bit currency) 
VT_DATE        DATE (double) 
VT_BSTR        BSTR 
VT_DISPATCH    IDispatch * 
VT_ERROR       HRESULT 
VT_BOOL        VARIANT_BOOL (True=-1, False=0) 
VT_VARIANT     VARIANT * 
VT_UNKNOWN     IUnknown * 
VT_DECIMAL     16 byte fixed point 
VT_UI1         opaque byte

÷ ø , ÷ , ÷ ( variant ) :

VT_ARRAY   Указывает, что вариант содержит массив SAFEARRAY 
VT_BYREF   Указывает, что вариант является ссылкой

API- VARIANT :

// initialize a variant to empty 
  // обнуляем вариант 
void    VariantInit(VARIANTARG * pvarg); 

  // release any resources held in a variant 
  // освобождаем все ресурсы, используемые в варианте 
HRESULT VariantClear(VARIANTARG * pvarg); 

  // deep-copy one variant to another 
  // полностью копируем один вариант в другой 
HRESULT VariantCopy(VARIANTARG * plhs, VARIANTARG * prhs); 

  // dereference and deep-copy one variant into another 
  // разыменовываем и полностью копируем один вариант в другой 
HRESULT VariantCopyInd(VARIANT * plhs, VARIANTARG * prhs); 

// convert a variant to a designated type 
// преобразуем вариант к указанному типу 
HRESULT VariantChangeType(VARIANTARG * plhs, 
    VARIANTARG * prhs, USHORT wFlags, VARTYPE vtlhs); 

// convert a variant to a designated type 
// преобразуем вариант к указанному типу (с явным указанием кода локализации) 
HRESULT VariantChangeTypeEx(VARIANTARG * plhs, 
    VARIANTARG * prhs, LCID lcid, USHORT wFlags, VARTYPE vtlhs);

÷ VARIANT '. × , API-, , VARIANT ÷ [in] -:

HRESULT UseIt([in] VARIANT var);

, ÷:

VARIANT var; 
VariantInit(&var);
  // initialize VARIANT 
  // инициализируем VARIANT 
V_VT(&var) = VT_I4; 
  // set discriminator 
  // устанавливаем дискриминатор 
V_I4(&var) = 100; 
  // set union 
  // устанавливаем объединение 
HRESULT hr = pItf->UseIt(var); 
  // use VARIANT 
  // используем VARIANT 
VariantClear(&var);
  // free any resources in VARIANT 
  // освобождаем все ресурсы VARIANT

, ÷ (accessor) VARIANT .

V_VT(&var) = VT_I4; 
V_I4(&var) = 100;

, :

var.vt = VT_I4; 
var.lVal = 100;

÷, -, .

, ø VARIANT ÷ :

STDMETHODIMP MyClass::UseIt( /*[in] */ VARIANT var) 
{
      // declare and init a second VARIANT 
      // объявляем и инициализируем второй VARIANT 
    VARIANT var2; 
    VariantInit(&var2);
      // convert var to a BSTR and store it in var2 
      // преобразуем переменную в BSTR и заносим ее в var2 
    HRESULT hr = VariantChangeType(&var2, &var, 0, VT_BSTR); 
      // use the string 
      // используем строку 
    if (SUCCEEDED(hr)){ 
        ustrcpy(m_szSomeDataMember, SAFEBSTR(V_BSTR(&var2))); 
          // free any resources held by var2 
          // освобождаем все ресурсы, поддерживаемые var2 
        VariantClear(&var2); 
    } 
    return hr; 
}

, ÷ API- VariantChangeType VARIANT ( ÷ BSTR ).

, , - . ÷ . , ÷:

HRESULT GetObject([out] IDog **ppDog);

, ÷ . ÷ IDL [iid_is] :

HRESULT GetObject([in] REFIID riid, [out, iid_is(riid)] IUnknown **ppUnk);

ø, ÷ - QueryInterface :

HRESULT GetObject([in] REFIID riid, [out, iid_is(riid)] void **ppv);

[iid_is] [in] , [out] IUnknown * void * . ÷ ÷ , IID :

IDog *pDog = 0;
HRESULT hr = pItf->GetObject(IID_IDog, (void**)&pDog);

QueryInterface :

STDMETHODIMP Class::GetObject(REFIID riid, void **ppv)
{
    extern IUnknown * g_pUnkTheDog; 
    return g_pUnkTheDog->QueryInterface(riid, ppv); 
}

ø ÷ ÷ ÷ IUnknown .


1 OLECHAR ÷ TCHAR , Wn32 API, ÷ ( CHAR WCHAR ). , ÷ UNICODE, .

2 _UNCC _U wchart * char * . ø , ÷ , ÷ ÷, ÷ . , API , ÷ ÷ _UNCC ÷ ÷.

3 ustring.h ÷ , ATL MFC , ll . ÷ .

4 VARIANTARG . VARIANTARG , . VARIANT , . VARIANTARG VARIANT , ÷.