我想用vc做的ocx接收从vb传来的数组..应该怎么写?vc的ocx的属性里没有数组的定义...
请大家帮忙..谢谢...

解决方案 »

  1.   

    如何在vc中定义这个数组..要定义为ocx的属性..但是classwizard中属性定义没有数组..再次感谢
      

  2.   

    定义成VARIANT,VARIANT里面能存放safearray
      

  3.   

    构造一个二维数组的SafeArray,然后把指针保存到VARIANT中就行。
    多了解SafeArray的使用。
      

  4.   

    safearray应该是在vb里定义,vc中只是定义一个variant准备接收既可以了对不对??
      

  5.   

    safearray应该是在vb里定义,vc中只是定义一个variant准备接收既可以了对不对??
    ------------------------------------
    safearray 是 c 里面的,其他语言 vb, javascript 中的数组传递到 com 中就是safearray 。
    在 com 中,可以用 variant 来保存 safearray 。
      

  6.   

    to:r_swordsman:那我在vc中定义接口函数的参数的时候定义成什么类型的?你说的我有点不明白,我先把我的问题说明白,我是想从vb中传一个二维数组到vc中,这个数组在接口函数的参数里,我这个参数应该定义成什么类型呢,在vb中又该如何定义呢???还有一个问题,我把safearray里的数读到数组中,结果第一个值不对,是个很大的六位数,其余的值都正确,我读的是二维数组,为什么???
      

  7.   

    上面已经说了啊...在 com 中,可以用 variant 来保存 safearray   。 你用 variant 类型即可
      

  8.   

    还有一个问题,我把safearray里的数读到数组中,结果第一个值不对,是个很大的六位数,其余的值都正确,我读的是二维数组,为什么???
    ----------------
    是把safearray读到c++的2维数组中不?
    你会操作吗?看看代码
      

  9.   

    我就是读到c++的二维数组中,一下是代码:
    vaResult.vt = VT_ARRAY|VT_R8;
        vaResult.parray = psa;

        for(long m=0;m<4;m++)
        {
            for(long n=0;n<10;n++)
            {
               // long index = m*10+n;  
      Demen[1]=m;
                  Demen[0]=n;
                 
                  SafeArrayGetElement(vaResult.parray,Demen,zz);
              //  SafeArrayGetElement(vaResult.parray,&index,*(zz+index));
    CString ss;
    ss.Format("%d",zz[m][n]);
                MessageBox(ss);
            }
        }
      

  10.   

    8楼的不严谨:...其他语言vb,javascript中的数组传递到com中就是safearray...vb是safearray,javascript(jscript)是 IDispatchEx
      

  11.   

    8楼的不严谨: ...其他语言vb,javascript中的数组传递到com中就是safearray... vb是safearray,javascript(jscript)是   IDispatchEx 
    ------------------------呵呵...那请问你是如果操作从javascript(jscript)传递到com中的数组呢?
      

  12.   

    呵呵...那请问你是如果操作从javascript(jscript)传递到com中的数组呢?到网上搜馊很多的,大致有两种办法:1. 直接调用 IDispatch(Ex) 的 Invoke(Ex) 方法,因为jscript的数组元素值可以看作“名字为数字的属性值”2.(代码来自网上)把javascript,vbscript中得数组传递给COM组件(or Activex) 
     
    COM组件的方法在IDL中的声明:
    [id(1), helpstring("方法InputArray")] HRESULT InputArray([in] VARIANT vData);在脚本中建立数组并调用COM组件的方法:
    当数组很大的时候,like 100k ,javascript在给数组赋值的时候效率非常低!完成时间,cpu占用率,
    占用的内存都大的可怕。反而VBScript却完成的很好。COM组件的代码:
    从代码中可以看到vbscript传进来的是个SafeArray。而javascript的情况就复杂了,javascript中得
    数组并不是真正意义上的数组,这个“数组”传到COM中被放进一个集合里,参数VARIANT的类型被置
    为VT_DISPATCH,我们得通过这个IDispatch指针调用invoke才能得到用来读取集合的枚举接口。STDMETHODIMP CBigParamCtl::InputArray(VARIANT vData)
    {
     LPBYTE p ;
     
     DWORD nLen; HRESULT hr; if( vData.vt == VT_DISPATCH)
     { 
      //deal with javascript array
      hr = VariantEnumToBytes(vData.pdispVal,&p,  &nLen);
     }
     else
     {
      //deal with vbscript array
      hr = VariantArrayToBytes(&vData, &p,  &nLen) ;
     }
     if(  S_OK ==  hr)
     {
      //....... do sth on p  
      delete[] p;
     } 
     return S_OK;
    }HRESULT VariantEnumToBytes(IDispatch* disp, LPBYTE *ppBytes, DWORD *pdwBytes)
    {
     // DebugBreak();
     HRESULT hr;
     DISPPARAMS noArgs = { NULL, NULL, 0, 0 };
     CComVariant resultV;
     hr = disp->Invoke( DISPID_NEWENUM,
      IID_NULL,
      LOCALE_SYSTEM_DEFAULT,
      DISPATCH_PROPERTYGET,
      &noArgs,
      &resultV,
      NULL,
      NULL );
     if( FAILED( hr ) && FAILED( resultV.ChangeType( VT_UNKNOWN ) ) )
      return E_FAIL;
     // Bug 37459, above Invoke succeeds, but returns resultV.vt == VT_EMPTY, resultV->other param unchanged
     if (resultV.vt != VT_UNKNOWN && resultV.vt != VT_DISPATCH)
     {
      return E_FAIL;
     } 
     CComQIPtr pEnum( resultV.punkVal );
     if( !pEnum )
      return E_FAIL;
     // Count the elements
     *pdwBytes = 0;
     hr = S_OK;
     
     //Get Enum Size
     while( hr == S_OK )
     {
      hr = pEnum->Skip(1);
      if( hr == S_OK )
       (*pdwBytes)++;
     }
     //allocate memory
     *ppBytes = (LPBYTE)new BYTE[*pdwBytes]; int nCount = 0;
     CComVariant elemV;
     pEnum->Reset();
     hr = S_OK;
     while( hr == S_OK )
     {
      // Could switch to use Skip when Cary gets
      // it working.
      hr = pEnum->Next( 1, &elemV, NULL );
      if( elemV.vt != VT_I4 )
       hr = S_FALSE; // correct for dispproxy bug 19307
      else
      {
       int nTmp = elemV.lVal;
       (*ppBytes)[nCount] = (BYTE)nTmp;
      } 
      if( hr == S_OK )
       nCount++;
     }
     return S_OK;
    }HRESULT VariantArrayToBytes(VARIANT *pVariant, LPBYTE *ppBytes, DWORD *pdwBytes)
    {
     USES_CONVERSION;
     if (pVariant->vt != (VT_VARIANT | VT_BYREF))
      return E_INVALIDARG; if (!(pVariant->pvarVal->vt & VT_ARRAY))
      return E_INVALIDARG; SAFEARRAY* pX = NULL;
     
     if (pVariant->pvarVal->vt & VT_BYREF)
      pX = *(pVariant->pvarVal->pparray);
     else
      pX = pVariant->pvarVal->parray; if (::SafeArrayGetDim(pX) != 1)
      return E_INVALIDARG;
        *ppBytes = NULL;
        *pdwBytes = 0;  VARIANT *pArray = NULL;
      HRESULT hr = E_FAIL;  _variant_t v;
     hr = SafeArrayAccessData(pX, (void **) &pArray );
     if( SUCCEEDED(hr))
     {
      *pdwBytes = pX->rgsabound->cElements;
      *ppBytes = (LPBYTE)new BYTE[*pdwBytes];  for( DWORD i = 0; i < *pdwBytes; i++)
      {
       v = pArray[i];
       v.ChangeType(VT_UI1);
       (*ppBytes)[i] = v.bVal;
      }  SafeArrayUnaccessData( pX );
     }
     else
      return hr;
     SafeArrayDestroy(pX);
     return S_OK;
    }
      

  13.   

    呵呵....我还以为javascript中的数组传递到com中不是 safearray呢看上面的代码...原来也是嘛....哈哈...safearray 就是用来在各中语言直接传递数组的.
      

  14.   

    给lz的例子,如何处理vb的数组, 注释掉的方法也可以,实现同样的功能,非线程安全:STDMETHODIMP CSimpleObjectA::put_SafeArray(VARIANT newVal)
    {
    if(newVal.vt == ::VT_ARRAY | ::VT_I4)
    {
    LPSAFEARRAY parr = newVal.parray; //if(parr->cDims == 1 && parr->rgsabound[0].cElements <= 100)
    //{
    // memset(m_array, 0x0, 400);
    // ULONG l =  parr->rgsabound[0].cElements;
    // int* p = (int*)parr->pvData;
    // for(ULONG i = 0; i < l; i++)
    // {
    // m_array[i] = p[i];
    // }
    //} LONG l = 0;
    if(::SafeArrayGetDim(parr) == 1 && ::SafeArrayGetUBound(parr, 1, &l) == S_OK && l < 100) // 0 - 99
    {
    memset(m_array, 0x0, 400);
    int v = 0;
    for(LONG i = 0; i < l; i++)
    {
    if(::SafeArrayGetElement(parr, &i, &v) == S_OK) m_array[i] = v;
    }
    }
    } return S_OK;
    }
    vb 中调用:
    Private Sub Command1_Click()
    Dim p(99) As Long ' I4, 0 - max indexp(0) = 23
    p(1) = 25Dim a As AltComTestA3.CSimpleObjectA
    Set a = New AltComTestA3.CSimpleObjectAa.SafeArray = pEnd Sub
      

  15.   

    vaResult.vt   =   VT_ARRAY ¦VT_R8; 
            vaResult.parray   =   psa;         for(long   m=0;m <4;m++) 
            { 
                    for(long   n=0;n <10;n++) 
                    { 
                          //   long   index   =   m*10+n;     
        Demen[1]=m; 
                                Demen[0]=n; 
                              
                                SafeArrayGetElement(vaResult.parray,Demen,zz); <------- zz 参数不对, 你的zz应该是 c++ 的二维数组, 改为类似 &zz[m][n]
                        //     SafeArrayGetElement(vaResult.parray,&index,*(zz+index)); 
    CString   ss; 
    ss.Format("%d",zz[m][n]); 
                            MessageBox(ss); 
                    } 
            }
      

  16.   

    呵呵....我还以为javascript中的数组传递到com中不是   safearray呢 
    看上面的代码...原来也是嘛....哈哈... 
    safearray   就是用来在各中语言直接传递数组的.楼上的,我两个都给出了,你到底看清楚了没有?!
      

  17.   

    谢谢大家..等东西弄好了一块结贴..我闲仔细看看大家的方法..我不用java.用vb传给vc做的ocx
      

  18.   

    还是不行...我觉得大家很多回答的怎么都不是我问的呢??
    我就是一个问题,如何把vb中的二维数组传到vc写的ocx中,用safearray和variant...
      

  19.   

    CComQIPtr pEnum( resultV.punkVal );
    这句在VC2005下编译不过
      

  20.   

    正在学习用javascript向com传递数组参数,学习下