用指针:
Byref YourArray
或者
用Varptr(YourArray)
取出指针
然后用
Byval传入

解决方案 »

  1.   

    VB 中, 数组变量 保存的是 数组描述符 的地址,所以 可以用 如下 方法:ByVal VarPtr(MyArray)
      

  2.   

    数组是有类型的,如果是字串则不行了。但若是其它类型,则可以用指针编移量去读每一个元素。
    所以你要用定长字串。
    同时须注意
    VB传入到VC的是定长BSTR类型的字串!!!!!!!!!
      

  3.   

    你还可以在VC 中直接定义一个BSTR类型的数组,
    然后用 &UrArray 方法获取数组。&:取地址操作符
    总会用吧? 
      

  4.   

    回复人: sonicdater(发呆呆(我答问题*不吵架*因为我呆)) (  ) 信誉:100  2002-2-26 20:43:58  得分:0  
      
    Bardo 好快呀 
    再快也无用,他问题未解决!不是吗?
      

  5.   

    《Advanced Visual Basic》上有 相关 内容。
     建议 去 读读。
      

  6.   

    我怎么没法取数组的地址?我定义了如下的数组:
            Dim MyStrings() as String
            Dim StringsAddr as Long
             
            ReDim MyStrings(3)        MyStrings(0) = "String1"
            MyStrings(1) = "String2"
            MyStrings(2) = "String3"        StringsAddr = VarPtr(MyStrings)结果全编译时就提示出错:Type Mismatch, 定位在MyStrings上。
      

  7.   

    用 Byref MyStrings 即可以传入地址
    不需要VarPtr
    因为MyStrings不中变体数组,所以会出错!(Type  Mismatch)
      

  8.   

    By Ref怎么定义呢?Declare里面根本不支持数组类型的。
      

  9.   

    非常漂亮,很简单就用as any
    =============================
    很少上网,在网上认识的朋友也不多。到这个论坛上来也没多长时间,但给我留下深刻印象的可就是你这个: Bardo(巴顿) 将军了。:)
      

  10.   

    to Bardo(巴顿):
      我定义了ByRef MyStrings as any, 但是以数组名作为参数传入的时候还是提示Type Mismatch.
      

  11.   

    我估计是:
    定义时把该参数设为:Byref …… As LongDim DataStr() as string
    Dim DataLng() as long
    Dim DataLen as long
    dim i as longDataLen=……
    ReDim DataStr(1 to DataLen)
    ReDim DataLng(1 To DataLen)DataStr(……)=……For i=1 to DataLen
        DataLng(i)=StrPtr(DataStr(i))
    Next iCall ……(……,DataLng(0),DataLen,……)
      

  12.   

    那你就用Type封装你的数组(VC:Struct)
    这是一定可行的!!!
    同样:用相同的结构名
    然后:
    AS 你的结构
      

  13.   

    有个 VarPtrStringArray 函数
      

  14.   

    不过 它得到的 好象不是 StringArray 的地址指针.
    得到的 是临时数组的 指针.你试试看.
      

  15.   

    VB数组用的是SafeArray,在<<HardCore VB>>里面详细解释过如何操作这个东西,相信对于VC的编程也是有启发的
      

  16.   

    to zyl910(910:分儿,我来了!) :
      我用你的方法,编译通过了。我的DLL中是把数组中的每一个字符串用MessageBox显示出来,但是实际显示只是每个字符串的第一个字符。请问这是什么原因?
      

  17.   

    回复人: chcw() (  ) 信誉:100  2002-3-2  12:09:18  得分:0  
     
     
      to  zyl910(910:分儿,我来了!)  :
          我用你的方法,编译通过了。我的DLL中是把数组中的每一个字符串用MessageBox显示出来,但是实际显示只是每个字符串的第一个字符。请问这是什么原因? 
    数组被转换成了LPCTSTR
      

  18.   

    to Bardo(巴顿):
      那怎么解决此问题呢?
      

  19.   

    改用Byte数组的数组!下面代码演示了两种语言间字串的转换
    VC++ and Win32 use the string data types LPSTR and LPWSTR. Function BSTRtoLPSTR(sBSTR As String, b() As Byte, lpsz As Long) As Long' Input: a nonempty BSTR string
    ' Input: **undimensioned** byte array b()
    ' Output: Fills byte array b() with ANSI char string
    ' Output: Fills lpsz with a pointer to b() array
    ' Returns byte count, not including terminating null
    ' Original BSTR is not affectedDim cBytes As Long
    Dim sABSTR As StringcBytes = LenB(sBSTR)' ReDim array, with space for terminating null
    ReDim b(1 To cBytes + 2) As Byte' Convert to ANSI
    sABSTR = StrConv(sBSTR, vbFromUnicode)' Point to BSTR char array
    lpsz = StrPtr(sABSTR)' Copy the array
    CopyMemory b(1), ByVal lpsz, cBytes + 2' Point lpsz to new array
    lpsz = VarPtr(b(1))' Return byte count
    BSTRtoLPSTR = cBytesEnd FunctionFunction BSTRtoLPWSTR(sBSTR As String, b() As Byte, lpwsz As Long) As Long' Input: a nonempty BSTR string
    ' Input: **undimensioned** byte array b()
    ' Output: Fills byte array b() with Unicode char string from sBSTR
    ' Output: Fills lpwsz with a pointer to b() array
    ' Returns byte count, not including terminating 2-byte Unicode null character
    ' Original BSTR is not affectedDim cBytes As LongcBytes = LenB(sBSTR)' ReDim array, with space for terminating null
    ReDim b(1 To cBytes + 2) As Byte' Point to BSTR char array
    lpwsz = StrPtr(sBSTR)' Copy the array
    CopyMemory b(1), ByVal lpwsz, cBytes + 2' Point lpsz to new array
    lpwsz = VarPtr(b(1))' Return byte count
    BSTRtoLPWSTR = cBytesEnd FunctionFunction LPWSTRtoBSTR(ByVal lpwsz As Long) As String' Input: a valid LPWSTR pointer lpwsz
    ' Return: a sBSTR with the same character arrayDim cChars As Long' Get number of characters in lpwsz
    cChars = lstrlenW(lpwsz)' Initialize string
    LPWSTRtoBSTR = String$(cChars, 0)' Copy string
    CopyMemory ByVal StrPtr(LPWSTRtoBSTR), ByVal lpwsz, cChars * 2End FunctionFunction LPSTRtoBSTR(ByVal lpsz As Long) As String' Input: a valid LPSTR pointer lpsz
    ' Output: a sBSTR with the same character arrayDim cChars As Long' Get number of characters in lpsz
    cChars = lstrlenA(lpsz)' Initialize string
    LPSTRtoBSTR = String$(cChars, 0)' Copy string
    CopyMemory ByVal StrPtr(LPSTRtoBSTR), ByVal lpsz, cChars' Convert to Unicode
    LPSTRtoBSTR = Trim0(StrConv(LPSTRtoBSTR, vbUnicode))End Function
    Public Function Trim0(sName As String) As String
       ' Right trim string at first null.
       Dim x As Integer
       x = InStr(sName, vbNullChar)
       If x > 0 Then Trim0 = Left$(sName, x - 1) Else Trim0 = sName
    End Function
      

  20.   

    HOWTO: Pass a SafeArray of Strings in a VARIANT* --------------------------------------------------------------------------------
    The information in this article applies to:The Microsoft Foundation Classes (MFC), used with:
    Microsoft Visual C++, 32-bit Editions, versions 2.0, 2.1, 2.2, 4.0, 4.0a, 4.1, 4.2, 4.2b, 5.0, 6.0--------------------------------------------------------------------------------
    SUMMARY
    When you look at the information available on passing SafeArrays between Visual C++ and Visual Basic, most pass the SafeArray in a parameter of type VARIANT. In MFC, this translates into a "const VARIANT& varName" parameter.As an alternative, this article explores how to pass a VARIANT*, which in MFC will be declared as a "VARIANT FAR* varName" parameter. Why should you use one method over the other? Because most applications allow modifications to a SafeArray passed in a VARIANT, but not all. In Excel 95, you can pass a SafeArray in a VARIANT to a Visual C++ server, modify the values in the server, return the modified SafeArray, and there is no change in Excel 95. Another reason to use this technique is to work around a limitation in Visual Basic when you use early binding. MORE INFORMATION
    To demonstrate this concept, start with a new "MFC AppWizard(exe)" project called StrArray. In "Step 3 of 6," select Automation, and then click Finish and OK to generate the project files. Now create a single automation method using ClassWizard. In ClassWizard, select "CStrArrayDoc" under "Class name:". Click the Automation tab and click Add Method. Enter the following values into the Add Method dialog box: 
       External Name : Sort
       Internal Name : Sort
       Return Type   : long
       Parameter List:      Name       : vArray
          Type       : VARIANT* 
    Click OK and Edit Code. To implement the Sort method, use the FastSort method of the MFCARRAY sample mentioned in the REFERENCES section below. This allows you to see the differences between passing the parameter as a "const VARIANT& varName" and a "VARIANT* varName". Modify the Sort method as follows:    ...
       #include <afxpriv.h>
       ...
       long CStrArrayDoc::Sort(VARIANT FAR* vArray)
       {      long i, j, min;
          BSTR bstrTemp;
          SAFEARRAY FAR* psa = NULL;
          BSTR HUGEP *pbstr;
          HRESULT hr;
          DWORD dwTimeStart;
          LONG cElements, lLBound, lUBound;      USES_CONVERSION;      // Type check VARIANT parameter. It should contain a BSTR array
          // passed by reference. The array must be passed by reference it is
          // an in-out-parameter.
          if (V_VT(vArray) != (VT_ARRAY | VT_BSTR))
             AfxThrowOleDispatchException(1001,
               "Type Mismatch in Parameter. Pass a string array by reference");
          psa = V_ARRAY(vArray);
          // Check dimensions of the array.
          if (SafeArrayGetDim(psa) != 1)
             AfxThrowOleDispatchException(1002,
               "Type Mismatch in Parameter. Pass a one-dimensional array");      dwTimeStart = GetTickCount();      // Get array bounds.
          hr = SafeArrayGetLBound(psa, 1, &lLBound);
          if (FAILED(hr))
              goto error;
          hr = SafeArrayGetUBound(psa, 1, &lUBound);
          if (FAILED(hr))
              goto error;      // Get a pointer to the elements of the array.
          hr = SafeArrayAccessData(psa, (void HUGEP* FAR*)&pbstr);
          if (FAILED(hr))
             goto error;      // Bubble sort.
          cElements = lUBound-lLBound+1;
          for (i = 0; i < cElements-1; i++)
          {
             min = i;
             for (j = i+1; j < cElements; j++)
             {
                // NULL is a valid value for a BSTR. This code treats a NULL
                // BSTR as less than other string values.
                if (pbstr[min] == NULL)
                   continue;
                else if (pbstr[j] == NULL
                   || wcscmp(pbstr[j], pbstr[min]) < 0)
                   min = j;
             }         //Swap array[min] and array[i].
             bstrTemp = pbstr[min];
             pbstr[min] = pbstr[i];
             pbstr[i] = bstrTemp;
          }      hr = SafeArrayUnaccessData(psa);
          if (FAILED(hr))
             goto error;      return GetTickCount()-dwTimeStart;   error:      AfxThrowOleDispatchException(1003,
            "Unexpected Failure in FastSort method");
          return 0;   } 
    Now you can build and test the automation server. After you build the server, run it as a stand-alone to register it. Run Visual Basic and create a new Visual Basic project. Place a button on the form and modify the handler to match the code below:    Private Sub Command1_Click()
          Dim o As Object
          Dim v As Variant
          ReDim v(50) As String
          Dim SortTime As Long      Set o = CreateObject("StrArray.Document")      upperbound = 1
          lowerbound = 100
          For n = 0 To 50
              v(n) = "Entry " & Int((upperbound-lowerbound+1)*Rnd+lowerbound)
          Next n      SortTime = o.Sort(v)
          MsgBox ("Done")
       End Sub 
    The key to getting this syntax to work in Visual Basic is to first Dim the array variable as a variant, and then ReDim it so that it becomes a variant containing an array of strings. Now you are ready to test the server. Set break points in the Visual Basic code before and after the call to Sort. Run the Visual Basic application, click Command1 and use the watch window to check the values for v. REFERENCES
    For more information, please see the following articles in the Microsoft Knowledge Base: Q122287 Limits of VB 3.0 Disptest as Automation Controllers 
    Q131046 SAMPLE: BINARY: Transfer Binary Data Using OLE Automation 
    Q131086 SAMPLE: SAFEARAY: Use of Safe Arrays in Automation 
    Q140202 SAMPLE: MFCARRAY: Using Safe Arrays in MFC Automation 
    Q122289 Passing Structures in OLE Automation 
    Q154172 How to Pass Binary Data Between an ActiveX Control and VB 
    Microsoft Systems Journal, June 1996, "Q&A OLE" by Don Box.