What does the structure or typedef look like for the SafeArray?

  1. 4 months ago

    ronaldo f

    Jul 1 Pre-Release Testers, Xojo Pro Philippines

    Hi Guys,

    In continue with my VB6 to XOJO conversion, I encountered "COM.SafeArray" from the imported ActiveX as seen from photo below.
    -image-

    What is it? How can I create it?

  2. Karen A

    Jul 1 Pre-Release Testers

    I goggled it:

    https://msdn.microsoft.com/en-us/magazine/mt778923.aspx

  3. Eugene D

    Jul 1 Pre-Release Testers, Xojo Pro Canada scispec.ca

    Hi Ronaldo,

    From Karen's helpful link, here are the two structures for SafeArray, which has one for 32-bit and another for 64-bit applications.

    This is for x86 applications:

    Structure tagSAFEARRAY32
      cDims as UInt16
      fFeatures as UInt16
      cbElements as UInt32
      cLocks as UInt32
      pvData as Ptr
      _spacer as UInt32
      rgsabound as Ptr
    End Structure

    This is for x64 applications:

    Structure tagSAFEARRAY64
      cDims as UInt16
      fFeatures as UInt16
      cbElements as UInt32
      cLocks as UInt32
      pvData as Ptr
      rgsabound as Ptr
    End Structure

    I confirmed the structures in Visual Studio C++ 2019.

  4. ronaldo f

    Jul 1 Pre-Release Testers, Xojo Pro Philippines

    thank you guys,

    But what I need is the XOJO conversion. I believed its illegal in xojo, right?

  5. Eugene D

    Jul 1 Pre-Release Testers, Xojo Pro Canada scispec.ca

    The code that is shown is the Xojo code of the structure.

  6. Julian S

    Jul 1 Pre-Release Testers, Xojo Pro UK
    Edited 4 months ago

    The structures are already in Xojo. I have no idea if this works and as I use COM so little, there might be a better way to do this, @William Y probably knows.

    Declare Function SafeArrayCreate Lib "OleAut32.dll" Alias "SafeArrayCreate" ( _
    vt As UInt16, _
    cDims As UInt32, _
    ByRef rgsabound As COM.SafeArrayBound _
    ) As Ptr
    
    Dim sab As COM.SafeArrayBound
    sab.lbound = 0
    sab.cElements = 10000 'the API says you need 10000 bytes
    
    Dim mb As New MemoryBlock(COM.SafeArray.Size)
    mb = SafeArrayCreate(17, 1, sab) '17 - bytes
    
    Dim t As COM.SafeArray
    t.StringValue(True) = mb.StringValue(0, COM.SafeArray.Size)
    
    Declare Function SafeArrayDestroy Lib "OleAut32.dll" Alias "SafeArrayDestroy" ( _
    psa As Ptr _
    ) As Int32
    
    Call SafeArrayDestroy(mb)
    
    'We can now use t here
    system.DebugLog("size=" + str(t.Size))

    Personally, if I were working on this project, I would change over to the DLL version of the API as I wouldn't be constantly fighting to figure out how Xojo uses/implements COM for the ActiveX version :)

  7. ronaldo f

    Jul 2 Pre-Release Testers, Xojo Pro Philippines

    I was amazed by Julian know how on this form of vb6 to xojo conversion. I believed that there is no detailed example or video demo available in the internet that show exactly what you have provided. Are you from xojo? It looks you know everything about things.

    " I would change over to the DLL version of the API" - I tried the DLL before but EVENTS are not exposed. Unlike ACTIVE X, everything is exposed.

    Actually, I have to use WINDOWS laptop to carry out the conversion. I wish I can do this on my macpro.

  8. Christian S

    Jul 2 Pre-Release Testers, Xojo Pro, XDC Speakers, Third Party Store Germany

    @Eugene D Hi Ronaldo,

    From Karen's helpful link, here are the two structures for SafeArray, which has one for 32-bit and another for 64-bit applications:

    I have doubts they are correct. This is C declaration:

    typedef struct tagSAFEARRAY
        {
        USHORT cDims;
        USHORT fFeatures;
        ULONG cbElements;
        ULONG cLocks;
        PVOID pvData;
        SAFEARRAYBOUND rgsabound[ 1 ];
        } 	SAFEARRAY;
    
    typedef struct tagSAFEARRAYBOUND
        {
        ULONG cElements;
        LONG lLbound;
        } 	SAFEARRAYBOUND;

    So rgsabound is not a ptr, but part of the structure providing the bounds.
    And the spacer may not be needed, if Xojo does aligning as C. (align structures on 8 byte boundaries for 64-bit)

  9. Eugene D

    Jul 2 Pre-Release Testers, Xojo Pro Canada scispec.ca

    Hi Christian,

    Yes, your right, the structure looks clearer when adding the array and using the tagSAFEARRAYBOUND structure. Here is the revised code from C++ to Xojo:

    Structure tagSAFEARRAY
      cDims as UInt16
      fFeatures as UInt16
      cbElements as UInt32
      cLocks as UInt32
      pvData as Ptr
      rgsabound(1) as tagSafeArrayBound
    End Structure
    Structure tagSAFEARRAYBOUND
      cElements as UInt32
      lBound as Int32
    End Structure

or Sign Up to reply!