想建立利用VC6.0和ATL建立一个Activex控件,接收VBscript脚本中传递进来的数组元素值作为坐标显示直线,试验中参考了http://blog.csdn.net/leechy/archive/2004/07/01/31773.aspx,利用VC的variant数据类型接收vbscript的safearray,但试验中老是出错,代码及错误如下:     首先利用Atl Com AppWizard建立ATL工程,然后利用Insert-->New Atl Object建立控件类,选择Control-->Full Control按照默认选项来建立Activex控件类。为接口IDrawLine添加属性(IDL接口定义文件中属性定义)如下:     [propput, id(3), helpstring("property InPutVbArray")] HRESULT InPutVbArray([in] VARIANT newVal);     建立控件类CDrawLine的数组成员,利用接口方法(属性)接收脚本传来的数组:     int * m_VbIntArray;     在类构造函数中初始化该成员:     m_VbIntArray=new int[2];
     m_VbIntArray[0]=100;
     m_VbIntArray[1]=100;     CdrawLine的OnDraw方法内容如下:     HRESULT OnDraw(ATL_DRAWINFO& di)
 {
  RECT& rc = *(RECT*)di.prcBounds;
  Rectangle(di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom);  SetTextColor(di.hdcDraw,RGB(0,255,255));  SetTextAlign(di.hdcDraw, TA_CENTER|TA_BASELINE);
  LPCTSTR pszText = _T("ATL 3.0 : DrawLine");
  TextOut(di.hdcDraw, 
   (rc.left + rc.right) / 2, 
   (rc.top + rc.bottom) / 2, 
   pszText, 
   lstrlen(pszText));  HPEN             hPen,hPenOld;
                hPen     = CreatePen( PS_SOLID, 1, RGB(0,255,255) );
  hPenOld  = (HPEN) SelectObject( di.hdcDraw, &hPen);
  
  MoveToEx(di.hdcDraw,rc.left+m_VbIntArray[0],    rc.bottom-m_VbIntArray[1], 0 );
  LineTo(   di.hdcDraw,rc.right,     rc.top );
  
  SelectObject(di.hdcDraw, &hPenOld );  DeleteObject(hPen);
  return S_OK;
 }  CDrawLine类中接口属性的输入方法及相关函数内容如下:  STDMETHODIMP CDrawLine::put_InPutVbArray(VARIANT newVal)
{
    // TODO: Add your implementation code here
    LPBYTE p ;
    DWORD nLen;
    HRESULT hr;
 
    hr = VariantArrayToBytes(&newVal, &p,  &nLen) ;
 if(  E_INVALIDARG ==  hr)
 {
     m_VbIntArray[0]=0;
     m_VbIntArray[1]=0;
 }
    
        if(  S_OK ==  hr)
 {
          //....... do sth on p 
   for(int i=0;i<2;i++)
   {
    m_VbIntArray[i]=(int)p[i];
   }
          delete[] p;
 }
    
     return S_OK;
}HRESULT CDrawLine::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) != 2)
       return E_INVALIDARG;*/   pX = pVariant->parray;
   //pX = pVariant->pvarVal->parray;
   //pX = *(pVariant->pvarVal->pparray);    *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[0].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;
}CDrawLine::VariantArrayToBytes方法中注释掉的内容是因为不注释掉的话后面的部分根本不会执行,程序编译通过,使用html脚本测试:<OBJECT
   classid="clsid:2E2BEB4E-530F-444B-A987-B151ACFB2499"
   id="ActivexDemo"
  >
  </OBJECT>
  <SCRIPT   LANGUAGE="VBScript"> 
   <!--  
      dim a
      a=Array(50,50)
      
      //dim a()
      //redim a(2)
      //a(0)=50
      //a(1)=50
      //a(2)=50
      
      ActivexDemo.InPutVbArray=a
      
   -->
  </SCRIPT>出现不同类型的错误,有兴趣可以试一下。后改变思路,修改和简化接口属性的输入方法如下:STDMETHODIMP CDrawLine::put_InPutVbArray(VARIANT newVal)
{
 // TODO: Add your implementation code here
 
        //deal with vbscript array
 VARIANT* v=&newVal;
    
 SAFEARRAY*   pS   =   v->parray;
 //SAFEARRAY*   pS   =   v->pvarVal->parray;
 //SAFEARRAY*   pS = *(v->pvarVal->pparray);//error
    
 unsigned   int   cdims;   
        //cdims   =   SafeArrayGetDim(pS);
 cdims=pS->cDims;
     
        if   (   cdims   ==   1   &  pS->rgsabound[0].cElements==4)
 {   
           USES_CONVERSION;   
       
    long * pNum;
    //SafeArrayAccessData(pS, (void**)&pNum);    //SafeArrayLock(pS);
    pNum=(long *)pS->pvData;
       
    
    m_VbIntArray[0]=pNum[2];
    m_VbIntArray[1]=pNum[2];    //SafeArrayUnlock(pS);
 }
    
    
 
    return S_OK;
}测试脚本如下:<OBJECT
   classid="clsid:2E2BEB4E-530F-444B-A987-B151ACFB2499"
   id="ActivexDemo"
  >
  </OBJECT>
  <SCRIPT   LANGUAGE="VBScript"> 
   <!--  
      ActivexDemo.Coordinate=50.0
      
      dim a
      a=Array(50,50,50,50)
      ActivexDemo.InPutVbArray=a
      
   -->
  </SCRIPT>只能取到pNum[2]的值并划线,其它元素值都取不到。而且只能使用Array定义VBscript数组,另外一种定义方法也不行,到底是什么原因也不知道,请高手予以指点。