精华内容
下载资源
问答
  • 主要实现vccom组件之间数据类型转换VARIANT与基本数据类型转换
  • //Create a BSTR and assign it to a Variant BSTR x = SysAllocString(L"Hello"); VARIANT myVariant; myVariant.vt = VT_BSTR; myVariant.bstrVal = x; SysFreeString(x); //Create a CString ...

    //Create a BSTR and assign it to a Variant
    BSTR x = SysAllocString(L"Hello");
    VARIANT myVariant;
    myVariant.vt = VT_BSTR;
    myVariant.bstrVal = x;
    SysFreeString(x);

    //Create a CString and change it to a variant;
    CString myCString(_T("My String"));
    CString mySecondString;


    //This is required to use the T2COLE macro.
    USES_CONVERSION;



    BSTR y = SysAllocString(T2COLE(myCString));
    myVariant.bstrVal = y;
    mySecondString = y;
    SysFreeString(y);


    //Create two BSTRs and add them.
    BSTR a = SysAllocString(L"One two ");
    BSTR b = SysAllocString(L"three four.");
    _bstr_t my_bstr_t(a, TRUE);
    my_bstr_t += b;
    myVariant.bstrVal = my_bstr_t;
    // or
    myVariant.bstrVal = _bstr_t(a, FALSE) + b;

    //Change a bstr to a CString.
    CString ANewString(b);
    //or if CString already exists.
    myCString = b;

    //Use of CComBSTR
    CComBSTR myCComBSTR(L"Hello");
    myCComBSTR.Append(L", how are you?");
    VARIANT varFromCCom;
    varFromCCom.vt = VT_BSTR;
    varFromCCom.bstrVal = myCComBSTR

    展开全文
  • 我们先看看COM所支持的一些类型的基本类: (微软提供,在comdef.h中定义) ... ..._bstr_t:对BSTR类型进行打包,并提供有用的操作和方法;..._variant_t:对VARIANT类型进行打包,并提供有用的操作和方法;

    我们先看看COM所支持的一些类型的基本类:

    (微软提供,在comdef.h中定义)

    在COM中使用的标准类Class如下所示:

    _bstr_t:对BSTR类型进行打包,并提供有用的操作和方法;

    _com_error:定义抛出的error对象;

    _com_ptr_t:封装COM接口指针

    _variant_t:对VARIANT类型进行打包,并提供有用的操作和方法;

    一、_variant_t类的简单介绍:

    _variant_t对象封装了VARIANT数据类型。

    The class manages resource allocation and deallocation and makes function calls to VariantInit and VariantClear as appropriate.

    (1) _variant类提供的方法:

    1> 构造函数

    _variant_t

    对_variant_t变量初始化调用的是_variant_t的构造函数。我们一般习惯于用一个int型的变量对数字类的变量进行初始化,这对_variant_t变量是不允许的。

    原因很简单,_variant_t 的构造函数中没有用整型( Int )对其初始化的构造函数

    可先将整型转化成long,然后再对其进行初始化

    2> Attach()

    Attaches a VARIANT object into the _variant_t object.

    3> Clear()

    Clears the encapsulated VARIANT object.

    4> ChangeType

    Changes the type of the _variant_t object to the indicated VARTYPE.

    5> Detach

    Detaches the encapsulated VARIANT object from this _variant_t object.

    6> SetString

    将一个string赋值给_variant_t对象;

    7> Operators

    赋值操作,给现有的_variant_t对象赋一个新值;

    8> operator ==, !=

    对比两个 _variant_t 对象是否相等;

    9> Extractors

    Extract data from the encapsulated VARIANT object.

    (2) _variant_t的定义:

    _variant_t类封闭了VARIANT数据类型,VARIANT是一个结构体类型,我们可以看一下它的定义

    1. typedef struct tagVARIANT   
    2. {  
    3.     VARTYPE vt;                             //存储数据类型  
    4.     unsigned short wReserved1;  
    5.     unsigned short wReserved2;  
    6.     unsigned short wReserved3;  
    7.     union   
    8.     {  
    9.         Byte bVal;                          // VT_UI1.  
    10.         Short iVal;                         // VT_I2.  
    11.         long lVal;                          // VT_I4.  
    12.         float fltVal;                       // VT_R4.  
    13.         double dblVal;                      // VT_R8.  
    14.         VARIANT_BOOL boolVal;               // VT_BOOL.  
    15.         SCODE scode;                        // VT_ERROR.  
    16.         CY cyVal;                           // VT_CY.  
    17.         DATE date;                          // VT_DATE.  
    18.         BSTR bstrVal;                       // VT_BSTR.  
    19.         DECIMAL FAR* pdecVal                // VT_BYREF|VT_DECIMAL.  
    20.         IUnknown FAR* punkVal;              // VT_UNKNOWN.  
    21.         IDispatch FAR* pdispVal;            // VT_DISPATCH.  
    22.         SAFEARRAY FAR* parray;              // VT_ARRAY|*.  
    23.         Byte FAR* pbVal;                    // VT_BYREF|VT_UI1.  
    24.         short FAR* piVal;                   // VT_BYREF|VT_I2.  
    25.         long FAR* plVal;                    // VT_BYREF|VT_I4.  
    26.         float FAR* pfltVal;                 // VT_BYREF|VT_R4.  
    27.         double FAR* pdblVal;                // VT_BYREF|VT_R8.  
    28.         VARIANT_BOOL FAR* pboolVal;         // VT_BYREF|VT_BOOL.  
    29.         SCODE FAR* pscode;                  // VT_BYREF|VT_ERROR.  
    30.         CY FAR* pcyVal;                     // VT_BYREF|VT_CY.  
    31.         DATE FAR* pdate;                    // VT_BYREF|VT_DATE.  
    32.         BSTR FAR* pbstrVal;                 // VT_BYREF|VT_BSTR.  
    33.         IUnknown FAR* FAR* ppunkVal;        // VT_BYREF|VT_UNKNOWN.  
    34.         IDispatch FAR* FAR* ppdispVal;      // VT_BYREF|VT_DISPATCH.  
    35.         SAFEARRAY FAR* FAR* pparray;        // VT_ARRAY|*.  
    36.         VARIANT FAR* pvarVal;               // VT_BYREF|VT_VARIANT.  
    37.         void FAR* byref;                    // Generic ByRef.  
    38.         char cVal;                          // VT_I1.  
    39.         unsigned short uiVal;               // VT_UI2.  
    40.         unsigned long ulVal;                // VT_UI4.  
    41.         int intVal;                         // VT_INT.  
    42.         unsigned int uintVal;               // VT_UINT.  
    43.         char FAR * pcVal;                   // VT_BYREF|VT_I1.  
    44.         unsigned short FAR * puiVal;        // VT_BYREF|VT_UI2.  
    45.         unsigned long FAR * pulVal;         // VT_BYREF|VT_UI4.  
    46.         int FAR * pintVal;                  // VT_BYREF|VT_INT.  
    47.         unsigned int FAR * puintVal;        //VT_BYREF|VT_UINT.  
    48.     };  
    49. };  
    注意:vt用来存储内部变量(联合体中保存的变量)的类型,联合体用来存储对应类型的值

    二、数据类型转换

    _bstr_t类可以作为_variant_t类与基本数据类型转换的中介

    (1) _variant_t与CString之间的转化

    1> CString转换为_variant_t:

    1. CString str;  
    2. _variant_t str1=(LPCTSTR)str;   
    使用_variant_t的成员函数SetString来对_variant_t的对象赋值会更好;

    2> _variant_t转换为CString:

    1. _variant_t vt;  
    2. CString tempstr=(LPCSTR)_bstr_t(vt);         //_bstr_t的构造函数有对_variant_t类型的处理  

    (2) _variant_t与char *之间的转换

    1> char * 转换为_variant_t

    方法与CString转换为_variant_t的方法类似:

    1. char * cValue;  
    2. _variant_t vValue=(LPSTR)cValue;  
    2> _variant_t转换为char *:

    错误方法:

    1. _variant_t vValue;  
    2. char * value=(LPSTR)(LPCSTR)_bstr_t(vValue)  

    value指向一堆乱码...

    原因:不能用char *直接指向(LPSTR)(LPCSTR)_bstr_t( _variant_t ),因为这样转换之后实际上是一个string,而非一个char *

    正确方法:

    进行转换时,只能用strcpy(),将LPSTR指向的字符复制到char * 所指向的内存中;

    如下例:

    1. _variant_t vValue;  
    2. char cValue[16]={0};  
    3. strcpy(cValue, (LPCSTR)_bstr_t(vValue));  

    (3) 判断_variant_t的值类型

    下面的转换代码根据_variant_t的vt进行类型判断,然后将数据值转换为CString类型(可作为转换为其他数据类型的中介)

    1. CString str;  
    2.   
    3. //以下代码演示如何转换为C标准字符串型  
    4. switch(var.vt)  
    5. {  
    6.     case VT_BSTR:  
    7.     {  
    8.         str=var.bstrVal;  
    9.         break;  
    10.     }  
    11.     case VT_I2: //var is short int type   
    12.     {  
    13.         str.Format("%d",(int)var.iVal);  
    14.         break;  
    15.     }  
    16.     case VT_I4: //var is long int type  
    17.     {  
    18.         str.Format("%d", var.lVal);  
    19.         break;  
    20.     }  
    21.     case VT_R4: //var is float type  
    22.     {  
    23.         str.Format("%10.6f", (double)var.fltVal);  
    24.         break;  
    25.     }  
    26.     case VT_R8: //var is double type  
    27.     {  
    28.         str.Format("%10.6f", var.dblVal);  
    29.         break;  
    30.     }  
    31.     case VT_CY: //var is CY type  
    32.     {  
    33.         str=COleCurrency(var).Format();  
    34.         break;  
    35.     }  
    36.     case VT_DATE: //var is DATE type  
    37.     {  
    38.         str=COleDateTime(var).Format();  
    39.         break;  
    40.     }  
    41.     case VT_BOOL: //var is VARIANT_BOOL  
    42.     {  
    43.         str= (var.boolVal==0) ?"FALSE""TRUE";  
    44.         break;  
    45.     }  
    46.     default:  
    47.     {  
    48.         str.Format("Unk type %d\n",var.vt);  
    49.         TRACE("Unknown type %d\n",var.vt);  
    50.         break;  
    51.     }  
    52. }  
    展开全文
  • Variant类型

    2012-02-06 12:58:00
    实际上,Variant类型对Pascal语言有普遍而深入的影响,Delphi 控件库中OLE 无关的地方也使用到这种类型。Variant变量没有类型 一般说来,你可以用Variant 变量存储任何数据类型,对它执行各种操作和类型转换。...

    为了完全支持OLE,32位Delphi 增加了Variant 数据类型,本节将从宏观角度来分析这种数据类型。实际上,Variant类型对Pascal语言有普遍而深入的影响,Delphi 控件库中与OLE 无关的地方也使用到这种类型。

    Variant变量没有类型

    一般说来,你可以用Variant 变量存储任何数据类型,对它执行各种操作和类型转换。需要注意的是:这违反了Pascal 语言的一贯原则,有悖于良好的编程习惯。variant 变量的类型检查和计算在运行期间才进行,编译器不会提示代码中的潜在错误,这些错误在进一步测试中才能发现。总之,你可以认为包含variant变量的代码是解释性代码,正如解释性代码一样,许多操作直到执行时才能知道,这对代码运行速度会有很大的影响。

    上面对Variant 类型的使用提出了警告,现在来看看Variant 类型究竟能干什么。基本上说,如果声明了一个variant 变量:

    var
      V: Variant;

    你就可以把各种不同类型的值赋给它:

    V := 10;
    V := 'Hello, World';
    V := 45.55;

    一旦得到一个variant 值,你可以把它拷贝给任何兼容或不兼容的数据类型。如果你把值赋给不兼容的数据类型,Delphi 会力尽所能进行转换,无法转换则颁布一个运行时间错误。实际上,variant变量中不仅包含了数据还包含有类型信息,并允许一系列运行时间操作,这些操作很方便,但运行速度慢且安全性差。

    见例VariTest,它是上面代码的扩展。窗体上有三个编辑框,一对按钮,第一个按钮的OnClick 事件代码如下:

    procedure TForm1.Button1Click(Sender: TObject);
    var
      V: Variant;
    begin
      V := 10;
      Edit1.Text := V;
      V := 'Hello, World';
      Edit2.Text := V;
      V := 45.55;
      Edit3.Text := V;
    end;

    很有趣是不是?你可以把一个值为字符串的variant 变量赋给编辑框Text 属性,还可以把值为整数或浮点数的variant 变量赋给Text属性。正如你在图10.1中所看到的,一切正常。

    (图10.1)按Assign按钮后,例VariTest的输出结果

    图 10.1: 例 VariTest 的 Assign 按钮 Click 事件输出结果

    更糟糕的是:你还可以用variant变量计算数值,从第二个按钮的Click事件代码就可看到这一点:

    procedure TForm1.Button2Click(Sender: TObject);
    var
      V: Variant;
      N: Integer;
    begin
      V := Edit1.Text;
      N := Integer(V) * 2;
      V := N;
      Edit1.Text := V;
    end;

    至少这种代码带有一定危险性,如果第一个编辑框包含了一个数字,那么一切运行正常;如果不是,将会引发异常。这里再重申一遍,如果不到万不得以,不要随便使用Variant 类型,还是应坚持使用传统的Pascal 数据类型和类型检查方法。在Delphi 和 VCL中,variant变量主要是用于 OLE 支持和数据库域的访问。

    Variant类型内部结构

    Delphi中定义了一个 variant 记录类型,TVarData,它与Variant 类型有相同的内存布局。你可以通过TVarData访问variant变量的实际类型。TVarData 结构中包含了Variant类型信息(由Vtype域表示)、一些保留域及当前值。

    VType域的取值包括OLE 自动化中的所有数据类型,这些类型通常叫OLE 类型或variant 类型。以下是variant 类型的完整列表,按字母顺序排列:

    • varArray
    • varBoolean
    • varByRef
    • varCurrency
    • varDate
    • varDispatch
    • varDouble
    • varEmpty
    • varError
    • varInteger
    • varNull
    • varOleStr
    • varSingle
    • varSmallint
    • varString
    • varTypeMask
    • varUnknown
    • varVariant

    你可以在Delphi 帮助系统的variants 主题下找到这些类型的说明。

    还有许多操作variant 变量的函数,你可以用它们进行特定的类型转换,或通过它们获取variant变量的类型信息(例如VarType 函数),当你用variant变量写表达式时,Delphi会自动调用这些类型转换和赋值函数。另外还有操作variant 数组的例程,你可以通过帮助文件的Variant support routines 主题了解相关内容。

    Variant类型运行很慢!

    Variant 类型代码运行很慢,不仅数据类型转换如此,两个值为整数的Variant 变量相加也是如此。它们几乎跟Visual Basic这种解释性代码一样慢!为了比较Variant变量和整型变量的运行速度,请看例VSpeed 。

    程序中设置了一个循环,记录运行时间并在进程条中显示运行状态。下面是基于variant类型的一段代码,基于整型的代码与此相似:

    procedure TForm1.Button1Click(Sender: TObject);
    var
      time1, time2: TDateTime;
      n1, n2: Variant;
    begin
      time1 := Now;
      n1 := 0;
      n2 := 0;
      ProgressBar1.Position := 0;
      while n1 < 5000000 do
      begin
        n2 := n2 + n1;
        Inc (n1);
        if (n1 mod 50000) = 0 then
        begin
          ProgressBar1.Position := n1 div 50000;
          Application.ProcessMessages;
        end;
      end;
      // we must use the result
      Total := n2;
      time2 := Now;
      Label1.Caption := FormatDateTime (
        'n:ss', Time2-Time1) + ' seconds';
    end;

    记时这段代码值得一看,因为你可以把它用到任何类型的性能测试中。正如你所看到的,程序用Now 函数获取当前的时间,用FormatDateTime 函数格式化时间差,输出结果以分("n")和秒("ss")表示。除此之外,你可以用Windows API的GetTickCount 函数,该函数能精确显示操作系统启动后至当前的毫秒数。

    从上例可见两者的速度差异非常之大,以至于不用精确记时也能看到这种差异。图10.2是在本人计算机上运行程序看到的结果。当然运行结果取决于运行程序的计算机,但是两者的数值比不会有太大变化。

    图 10.2: 例Vspeed中整型与Variant类型的计算速度差异

    结束语

    Variant类型与传统Pascal 数据类型差别很大,所以本章以短小篇幅单独阐述了Variant类型的有关内容。尽管Variant类型主要用于OLE 编程,但用来写一些潦潦草草的程序倒也便利,因为不用考虑数据类型,不过正如以上所述,这样做会影响程序执行速度。

    通过前面各章我们已经介绍了绝大部分的语言特征,下一章将讨论程序的总体框架和单元模块。

    展开全文
  • _variant_t相关类型之间的转换

    千次阅读 2015-05-15 16:14:08
    (1)字符串CString:  _variant_t temp;  CString str_wtdw;  str_wtdw=temp.bstrVal; ...(2)整数int: ... _variant_t temp;... //有时根据不同的整数类型需要采用相关的操作,例如:  value=temp.intVal;

    (1)与字符串CString:
     _variant_t temp;
     CString str_wtdw;
     str_wtdw=temp.bstrVal;


    (2)与整数int:

     _variant_t temp;
     int value;
     value=temp.iVal;
     //
    有时根据不同的整数类型需要采用相关的操作,例如:
     value=temp.intVal;


    (3)与浮点数double
     _variant_t temp;
     double value;
     value=temp.dblVal;


    (4)与日期型函数的转换

     _variant_t temp;
     DATE   dt;
     COleDateTime   odt;
     CString outdate;

     dt=temp.date;
     odt=COleDateTime(dt);

     outdate=odt.Format("%Y%m%d");
     //
    这种转换方式有些问题,如果月是6,可能会出现06月的情况


     year.Format("%d
    ",odt.GetYear());
     month.Format("%d
    ",odt.GetMonth());
     day.Format("%d
    ",odt.GetDay());

     outdate=year+month+day;



    展开全文
  • Delphi中Tobject与Variant之间的转换

    千次阅读 2012-07-20 13:28:05
    原本这两都一个是引用类型,一个是值类型,是不能互相转换的。但借助于string类型,两者可以互相转换,但并不推荐这样做。因为这样会降低程序的运行效率。 variant转tobject tobject(string(v)); tobject转string...
  • (1)字符串CString:  _variant_t temp;  CString str_wtdw;  str_wtdw=temp.bstrVal; ...(2)整数int: ... //有时根据不同的整数类型需要采用相关的操作,例如:  value=temp.intVal; (3)浮点
  • VARIANT与CString相互转换

    千次阅读 2007-12-26 14:39:00
    你也能自己编写返回 VARIANT 类型的方法,函数返回什么类型 依赖可能(并且常常)方法的输入参数(比如,在自动化操作中,依赖你调用哪个方法。IDispatch::Invoke 可能返回(通过其一个参数)一个 包含有BYTE、...
  • 你也能自己编写返回 VARIANT 类型的方法,函数返回什么类型 依赖可能(并且常常)方法的输入参数(比如,在自动化操作中,依赖你调用哪个方法。IDispatch::Invoke 可能返回(通过其一个参数)一个 包含有BYTE、...
  • 可以给相同的Variant分配不同的数据类型,只要Variant包含数字值就可以执行算法; variant数组只不过是variant型的数组,不必包含同类型的数据; 1、 VarArrayOf函数:更快捷的创建一维变体数组,可
  • 将用户自定义的C结构数据存储成VARIANT类型,需要时再将VARIANT类型转为用户自定义的结构数据,有十分现实的意义,既然我们不想为这样的结构数据写一个COM包装类。虽然有很多方法和手段生成这样的VARIANT,但是,...
  • 本节内容: 1、IDispatch的简介作用 ... 3、COM数据类型的转换 ...4、VARIANT类型的派生类 1、IDispatch的简介作用 •我们之前讲过COM组件是跨应用的。到目前为止,我们都只是通过C++来调用COM组件的接口
  • 因为近期工作需要完成OCX控件同时支持C#C++调用,所以接口设置就会遇上些问题。在需要将图片的内存数据(buffer)传入控件时,如果按照C++惯例,设计接口参数类型为unsigned char*,就会存在被C#识别为ref byte的...
  • Delphi 变体类型Variant)的介绍(流变体类型的相互转换、变体类型常用的函数) 一、变体类型常用的函数介绍: Variant: 一种可以拥有各种数据类型; 也可以告诉目前存储的数据是什么类型(通过使用VarType...
  • 可以给相同的Variant分配不同的数据类型,只要Variant包含数字值就可以执行算法; variant数组只不过是variant型的数组,不必包含同类型的数据; 1、 VarArrayOf函数:更快捷的创建一维变体数组,可以创

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 156
精华内容 62
关键字:

variant类型与转换