none
VC和IDL数据交换出现的问题 RRS feed

  • 问题

  • 我用vc通过activex方式调用idl,进行数据交换并画图;在vc中创建了一个支持activex自动化的对话框工程test2,在对话框上添加一个idl draw widget控件,并通过类向导在类ctest2dlg中添加cidldrawx3类型成员m_idl。将下面代码加入ctest2dlg::oninitdialog() 函数返回语句前:
    m_idl.initidl((long)m_hwnd);
    m_idl.createdrawwidget();
    BSTR aaa[8]={0};
    int *a=(int*)calloc(8,sizeof(int));
    for(int i=0;i <8;i++)
    {a[i]=i;}
    safearraybound rgsabound[1];
    rgsabound[0].llbound=0;
      rgsabound[0].celements=8;
      safearray*psa=safearraycreate(vt_r4,1,rgsabound);
    psa->pvdata=a;
    variant aa;
    variantinit(&aa);
    aa.vt=vt_array/vt_r4;
    aa.parray=psa;
    m_idl.setnamedarray("aaa",aa,0);(此条语句实现vc和idl的数据交换,aaa为idl中存储数据的数组,aa为vc中存储数据的地址)
    m_idl.executestr("plot,aaa");
    编译后没有问题,运行后出现idl ocx waring: idl_m_notarray:plot: expression must be an array in this context:aaa

    我前面明明已经定义了aaa为数组了,估计是在VC如何定义IDL中的数组出现了问题,请高手帮忙解答一下是怎么回事?感谢!

    2009年4月28日 6:43

全部回复

  • 高手帮忙解答一下啊,感谢了!!!
    2009年4月28日 23:43
  • 能看一下idl中setnamedarray接口的声明吗?

    2009年4月29日 0:58
    版主
  • 能看一下idl中setnamedarray接口的声明吗?

    SetNamedArray

    This method creates a named IDL array with the specified data. The data pointer is shared with IDL and the EDE application. Thus, changes in either IDL or the EDE will be reflected in both.

    Parameters

    BSTR: Name of array variable to create in IDL.

    VARIANT: Array data to be shared with IDL.

    BOOL: True if IDL should free a shared array when IDL releases its reference, false if not.

    Returns

    WORD: 1 if successful, 0 if set failed.

    Remarks

    Because SetNamedArray creates an array whose data is shared between IDL and the EDE application, IDL constructs that could change the type and/or dimensionality of the array must be avoided, as these constructs could have the side effect of creating a new array in IDL and thus breaking the shared link.

    The array parameter of SetNamedArray must have a lifetime beyond the calling function. Thus, in Visual Basic, it is recommended that the array be declared as global in scope to prevent runtime errors from occurring.

    Note
    In order to allow data to be shared between IDL and the external environment, the lock count on the underlying array is incremented. Some external environments, notably later versions of Delphi, do not allow array locking to extend beyond a single method call and will signal an error when SetNamedArray returns. If this occurs, the data cannot be shared between IDL and the external environment using SetNamedArray. Use the SetNamedData method to insert a copy of the array into IDL.

    The following table lists the accepted variant types and the corresponding IDL types.

    Table 8-5: Accepted Variant Types and the Corresponding IDL Types 

    Variant Types

    IDL Types

    VT_UI1 - unsigned char

    IDL_TYP_BYTE

    VT_I1 - signed char

    IDL_TYP_BYTE

    VT_I2 - signed short

    IDL_TYP_INT

    VT_I4 - signed long

    IDL_TYP_LONG

    VT_R4 - float

    IDL_TYP_FLOAT

    VT_R8 - double

    IDL_TYP_DOUBLE

    只有英文的说明,大家帮帮忙,懂的朋友说说看,感谢啊!!!
    2009年5月1日 0:43
  • 自己顶一下,高手帮忙解答一下啊,感谢!
    2009年5月3日 0:00
  • 需要进行数组的行列数转换。

    可以先调用下这个IDL功能

    FUNCTION CHANGEARRAYORDER, inArr
      ;
      oDims = SIZE(inArr,/dimension)
      oType = SIZE(inArr,/Type)
      nDims = SIZE(inArr,/N_dim)
      CASE nDims OF
        1:result = inArr
        2: BEGIN
          result = REFORM(inArr, oDims[1],oDims[0])
        END
        3: BEGIN
          result = REFORM(inArr,oDims[2],oDims[1],oDims[0])
        END
        ELSE: BEGIN
          cmdStr = 'result= Reform(inArr'
          FOR idx=nDims-1,0,-1 DO BEGIN
            cmdStr += ',oDims['+STRTRIM(iDx)+']'
          ENDFOR
          void = EXECUTE(cmdStr+')')
        END
      ENDCASE
     
      RETURN,result
    END

    2011年10月18日 10:14