Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. COM
  4. Re: Calling ActiveX DLL from MFC - passing arrays

Re: Calling ActiveX DLL from MFC - passing arrays

Scheduled Pinned Locked Moved COM
c++questioncom
8 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    mla154
    wrote on last edited by
    #1

    Hello, I have created a function in an ActiveX DLL similar to the function below:

    Public Function f1(ByRef arr1() As String, ByRef arr2() As Double) As String()
    End Function
    

    How do I create a SAFEARRAY in Visual C++ to successfully pass both of these arrays?

    Regards, Mike

    CPalliniC 1 Reply Last reply
    0
    • M mla154

      Hello, I have created a function in an ActiveX DLL similar to the function below:

      Public Function f1(ByRef arr1() As String, ByRef arr2() As Double) As String()
      End Function
      

      How do I create a SAFEARRAY in Visual C++ to successfully pass both of these arrays?

      Regards, Mike

      CPalliniC Offline
      CPalliniC Offline
      CPallini
      wrote on last edited by
      #2

      If you put SafeArray into CP article search engine, then a bit of magic happens http://www.codeproject.com/info/search.aspx?artkw=SafeArray&sbo=kw[^] :)

      If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
      [my articles]

      In testa che avete, signor di Ceprano?

      M 1 Reply Last reply
      0
      • CPalliniC CPallini

        If you put SafeArray into CP article search engine, then a bit of magic happens http://www.codeproject.com/info/search.aspx?artkw=SafeArray&sbo=kw[^] :)

        If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
        [my articles]

        M Offline
        M Offline
        mla154
        wrote on last edited by
        #3

        The data has been put into the SafeArray. However, when reading the data into the VB ActiveX DLL function, I wrote code to display the contents of the array:

        Public Function f1(ByRef arr1() As String, ByRef arr2() As Double) As String()
           ShowList arr1
        End Function
        
        Private Sub ShowList(ByRef arr() As String)
            for i1 = LBound(arr, 1) to UBound(arr, 1)
               MsgBox arr(i1)
            next i1
        End Sub
        

        The program crashes.

        Regards, Mike

        CPalliniC 1 Reply Last reply
        0
        • M mla154

          The data has been put into the SafeArray. However, when reading the data into the VB ActiveX DLL function, I wrote code to display the contents of the array:

          Public Function f1(ByRef arr1() As String, ByRef arr2() As Double) As String()
             ShowList arr1
          End Function
          
          Private Sub ShowList(ByRef arr() As String)
              for i1 = LBound(arr, 1) to UBound(arr, 1)
                 MsgBox arr(i1)
              next i1
          End Sub
          

          The program crashes.

          Regards, Mike

          CPalliniC Offline
          CPalliniC Offline
          CPallini
          wrote on last edited by
          #4

          That probably means that SafeArray initialization was wrong on the C++ (client) side. How do you perform that task? :)

          If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
          [my articles]

          In testa che avete, signor di Ceprano?

          M 1 Reply Last reply
          0
          • CPalliniC CPallini

            That probably means that SafeArray initialization was wrong on the C++ (client) side. How do you perform that task? :)

            If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
            [my articles]

            M Offline
            M Offline
            mla154
            wrote on last edited by
            #5

            SAFEARRAY* CreateASafeArray()
            {
            //http://www.geocities.com/Jeff\_Louie/safearray.html
            USES_CONVERSION; // enables use of ATL conversion macro A2W
            char buffer[20]; // used to store ANSI string
            HRESULT hr= S_OK;

            // Create SafeArray of VARIANT BSTRs
            SAFEARRAY \*pSA;
            SAFEARRAYBOUND aDim\[1\];    // a one dimensional array
            aDim\[0\].lLbound= 0;  // Visual Basic arrays start with index 0
            aDim\[0\].cElements= 10;
            pSA= SafeArrayCreate(VT\_VARIANT,1,aDim);  // create a 1D SafeArray of VARIANTS
            if (pSA != NULL) {
            	long aLong\[1\];
            	// iterate over array adding VARIANTs of type VT\_BSTR
            	for (long l= aDim\[0\].lLbound; l< (long)(aDim\[0\].cElements + aDim\[0\].lLbound); l++) { 
            		VARIANT vOut;
            		VariantInit(&vOut);
            		vOut.vt= VT\_BSTR;  // set type
            		\_ltoa\_s(l,buffer,10);  // convert long to ANSI string value
            		vOut.bstrVal= ::SysAllocString(A2W(buffer)); // system wide "new"
            		aLong\[0\]= l;  // set index value
            		if (hr= SafeArrayPutElement(pSA, aLong, &vOut)) { // "correctly" copies VARIANT
            			VariantClear(&vOut);  // release BSTR from memory on error
            			SafeArrayDestroy(pSA); // does a deep destroy on error
            			return NULL;
            		}
            		VariantClear(&vOut);  // does a deep destroy of source VARIANT
            	} // end iteration
            }
            return pSA;
            // clean up here only if you do not return SafeArray as an \[out, retval\]
            SafeArrayDestroy(pSA); // again does a deep destroy
            

            }

            void CaxDlg::OnBnClickedButton1()
            {
            SAFEARRAY *pSA3 = CreateASafeArray ();
            }

            Regards, Mike

            L 1 Reply Last reply
            0
            • M mla154

              SAFEARRAY* CreateASafeArray()
              {
              //http://www.geocities.com/Jeff\_Louie/safearray.html
              USES_CONVERSION; // enables use of ATL conversion macro A2W
              char buffer[20]; // used to store ANSI string
              HRESULT hr= S_OK;

              // Create SafeArray of VARIANT BSTRs
              SAFEARRAY \*pSA;
              SAFEARRAYBOUND aDim\[1\];    // a one dimensional array
              aDim\[0\].lLbound= 0;  // Visual Basic arrays start with index 0
              aDim\[0\].cElements= 10;
              pSA= SafeArrayCreate(VT\_VARIANT,1,aDim);  // create a 1D SafeArray of VARIANTS
              if (pSA != NULL) {
              	long aLong\[1\];
              	// iterate over array adding VARIANTs of type VT\_BSTR
              	for (long l= aDim\[0\].lLbound; l< (long)(aDim\[0\].cElements + aDim\[0\].lLbound); l++) { 
              		VARIANT vOut;
              		VariantInit(&vOut);
              		vOut.vt= VT\_BSTR;  // set type
              		\_ltoa\_s(l,buffer,10);  // convert long to ANSI string value
              		vOut.bstrVal= ::SysAllocString(A2W(buffer)); // system wide "new"
              		aLong\[0\]= l;  // set index value
              		if (hr= SafeArrayPutElement(pSA, aLong, &vOut)) { // "correctly" copies VARIANT
              			VariantClear(&vOut);  // release BSTR from memory on error
              			SafeArrayDestroy(pSA); // does a deep destroy on error
              			return NULL;
              		}
              		VariantClear(&vOut);  // does a deep destroy of source VARIANT
              	} // end iteration
              }
              return pSA;
              // clean up here only if you do not return SafeArray as an \[out, retval\]
              SafeArrayDestroy(pSA); // again does a deep destroy
              

              }

              void CaxDlg::OnBnClickedButton1()
              {
              SAFEARRAY *pSA3 = CreateASafeArray ();
              }

              Regards, Mike

              L Offline
              L Offline
              Lim Bio Liong
              wrote on last edited by
              #6

              Hello Michael, Your VB object method f1 declared arr1() as of type "string". Your CreateASafeArray() C++ function declared the SAFERRAY as holding elements of type VT_VARIANT. This is the problem : VT_VARIANT type is not a string. VT_BSTR is. To resolve the problem, either : 1. Change the signature of f1 to : Public Function f1(ByRef arr1() As Variant, ByRef arr2() As Double) As String() ShowList arr1 End Function or 2. Change the call to CreateSafeArray() in CreateASafeArray() function to : pSA= SafeArrayCreate(VT_BSTR,1,aDim); // create a 1D SafeArray of VARIANTS and then make the appropriate changes to the rest of the code in CreateASafeArray(). Hope the above suggestions will help you. Best Regards, Bio.

              M 1 Reply Last reply
              0
              • L Lim Bio Liong

                Hello Michael, Your VB object method f1 declared arr1() as of type "string". Your CreateASafeArray() C++ function declared the SAFERRAY as holding elements of type VT_VARIANT. This is the problem : VT_VARIANT type is not a string. VT_BSTR is. To resolve the problem, either : 1. Change the signature of f1 to : Public Function f1(ByRef arr1() As Variant, ByRef arr2() As Double) As String() ShowList arr1 End Function or 2. Change the call to CreateSafeArray() in CreateASafeArray() function to : pSA= SafeArrayCreate(VT_BSTR,1,aDim); // create a 1D SafeArray of VARIANTS and then make the appropriate changes to the rest of the code in CreateASafeArray(). Hope the above suggestions will help you. Best Regards, Bio.

                M Offline
                M Offline
                mla154
                wrote on last edited by
                #7

                Bio., Your second piece of advice allowed the string array to be read correctly.  Thank you.

                Regards, Mike

                modified on Thursday, January 10, 2008 11:52:12 AM

                L 1 Reply Last reply
                0
                • M mla154

                  Bio., Your second piece of advice allowed the string array to be read correctly.  Thank you.

                  Regards, Mike

                  modified on Thursday, January 10, 2008 11:52:12 AM

                  L Offline
                  L Offline
                  Lim Bio Liong
                  wrote on last edited by
                  #8

                  Congratulations, Michael. Best wishes to your project. - Bio.

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups