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. C / C++ / MFC
  4. Safearray of UDT

Safearray of UDT

Scheduled Pinned Locked Moved C / C++ / MFC
data-structurestestingtoolsperformancehelp
11 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.
  • K Offline
    K Offline
    Krouer
    wrote on last edited by
    #1

    I have an automation interface which own a UDT array. The UDT is define as struct NoteDesc { float base; float pitch; float medium; }; In my interface, I have set the get and put properties. put works really great but after I return from get, I have memory crash in the kernel. Here my interface def: [ object, uuid(60C22F90-D3BB-4BA0-ABCC-837E4CA2AEF2), dual, helpstring("IScoreDesc Interface"), pointer_default(unique) ] interface IScoreDesc : IDispatch { [propget, id(1)] HRESULT NumberOfNote([out, retval] long *pVal); [propput, id(1)] HRESULT NumberOfNote([in] long newVal); [propget, id(2)] HRESULT Notes([out, retval] SAFEARRAY(NoteDesc) *pVal); [propput, id(2)] HRESULT Notes([in] SAFEARRAY(NoteDesc) newVal); }; and the class compil well, the call to get is effective. The problem occur when I return of the function get define like that in my h file: STDMETHOD(get_Notes)(SAFEARRAY* *pVal); Do you have any idea?

    J E 2 Replies Last reply
    0
    • K Krouer

      I have an automation interface which own a UDT array. The UDT is define as struct NoteDesc { float base; float pitch; float medium; }; In my interface, I have set the get and put properties. put works really great but after I return from get, I have memory crash in the kernel. Here my interface def: [ object, uuid(60C22F90-D3BB-4BA0-ABCC-837E4CA2AEF2), dual, helpstring("IScoreDesc Interface"), pointer_default(unique) ] interface IScoreDesc : IDispatch { [propget, id(1)] HRESULT NumberOfNote([out, retval] long *pVal); [propput, id(1)] HRESULT NumberOfNote([in] long newVal); [propget, id(2)] HRESULT Notes([out, retval] SAFEARRAY(NoteDesc) *pVal); [propput, id(2)] HRESULT Notes([in] SAFEARRAY(NoteDesc) newVal); }; and the class compil well, the call to get is effective. The problem occur when I return of the function get define like that in my h file: STDMETHOD(get_Notes)(SAFEARRAY* *pVal); Do you have any idea?

      J Offline
      J Offline
      Joaquin M Lopez Munoz
      wrote on last edited by
      #2

      It'd be most helpful if you could post the actual implementation of your get_Notes function. Anything else seems to be OK. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

      K 1 Reply Last reply
      0
      • J Joaquin M Lopez Munoz

        It'd be most helpful if you could post the actual implementation of your get_Notes function. Anything else seems to be OK. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

        K Offline
        K Offline
        Krouer
        wrote on last edited by
        #3

        The source code of my function: (my comment are in french, don't take care of them) STDMETHODIMP CScoreDesc::get_Notes(SAFEARRAY **pVal) { // Remplis une structure d'information pour pouvoir créer le tableau IRecordInfo* pRecordInfo = NULL; HRESULT hr = GetRecordInfoFromGuids(LIBID_MUSICSEARCHSYSTEM, 1, 0, GetUserDefaultLCID(), IID_NodeDesc, &pRecordInfo); // Détruit le tableau si il existait déjà if (*pVal != NULL) { SafeArrayDestroy(*pVal); *pVal = NULL; } // Crée un tableau pour le transport *pVal = SafeArrayCreateVectorEx(VT_RECORD, 0, m_NumberOfNote, pRecordInfo); pRecordInfo->Release(); if (*pVal == NULL) { hr = Error(_T("Cannot create the Notes decription array")); return hr; } // Rempli le tableau avec le contenu du tableau interne NoteDesc* pNoteArray; hr = SafeArrayAccessData(*pVal, (void**) &pNoteArray); if FAILED(hr) return hr; memcpy(pNoteArray, m_Notes, sizeof(NoteDesc)*m_NumberOfNote); SafeArrayUnaccessData(*pVal); return S_OK; } The IID_NoteDesc is defined at the top of this cpp file. I have try to follow an article I found on this site write by Ioannis Stamatopoulos. Thanks, Bruno

        J 1 Reply Last reply
        0
        • K Krouer

          The source code of my function: (my comment are in french, don't take care of them) STDMETHODIMP CScoreDesc::get_Notes(SAFEARRAY **pVal) { // Remplis une structure d'information pour pouvoir créer le tableau IRecordInfo* pRecordInfo = NULL; HRESULT hr = GetRecordInfoFromGuids(LIBID_MUSICSEARCHSYSTEM, 1, 0, GetUserDefaultLCID(), IID_NodeDesc, &pRecordInfo); // Détruit le tableau si il existait déjà if (*pVal != NULL) { SafeArrayDestroy(*pVal); *pVal = NULL; } // Crée un tableau pour le transport *pVal = SafeArrayCreateVectorEx(VT_RECORD, 0, m_NumberOfNote, pRecordInfo); pRecordInfo->Release(); if (*pVal == NULL) { hr = Error(_T("Cannot create the Notes decription array")); return hr; } // Rempli le tableau avec le contenu du tableau interne NoteDesc* pNoteArray; hr = SafeArrayAccessData(*pVal, (void**) &pNoteArray); if FAILED(hr) return hr; memcpy(pNoteArray, m_Notes, sizeof(NoteDesc)*m_NumberOfNote); SafeArrayUnaccessData(*pVal); return S_OK; } The IID_NoteDesc is defined at the top of this cpp file. I have try to follow an article I found on this site write by Ioannis Stamatopoulos. Thanks, Bruno

          J Offline
          J Offline
          Joaquin M Lopez Munoz
          wrote on last edited by
          #4

          The only thing I can guess about your code is that maybe sizeof(NoteDesc) is not equal to the value provided by pRecordInfo->GetSize() due to alignment considerations. Could you check that out? Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

          K 1 Reply Last reply
          0
          • J Joaquin M Lopez Munoz

            The only thing I can guess about your code is that maybe sizeof(NoteDesc) is not equal to the value provided by pRecordInfo->GetSize() due to alignment considerations. Could you check that out? Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

            K Offline
            K Offline
            Krouer
            wrote on last edited by
            #5

            The error message: HEAP[musicserver.exe]: Invalid Address specified to RtlFreeHeap( 130000, 1e0690 ) The size return pRecordInfo->GetSize and sizeof(NoteDesc) are identical (value is 12 - 3 32bits floats) I don't know where it found to have to destroy this huge part of memory. My test array contains only 10 elements, that's 120 bytes. Not 722576 if I have understand correctly the trace from the HEAP. Thanks, Bruno

            J 1 Reply Last reply
            0
            • K Krouer

              The error message: HEAP[musicserver.exe]: Invalid Address specified to RtlFreeHeap( 130000, 1e0690 ) The size return pRecordInfo->GetSize and sizeof(NoteDesc) are identical (value is 12 - 3 32bits floats) I don't know where it found to have to destroy this huge part of memory. My test array contains only 10 elements, that's 120 bytes. Not 722576 if I have understand correctly the trace from the HEAP. Thanks, Bruno

              J Offline
              J Offline
              Joaquin M Lopez Munoz
              wrote on last edited by
              #6

              Well, this is wild guessing, but anyway... What client technology are you using? If it's ASP or other VB-based stuff, seems like VBSCRIPT does not handle SAFEARRAYs of objects other than VARIANTs (read MSDN article PRB: Script Error Occurs When Referencing Non-variant Array (Q165967)). Also, if your client is written in C#, I've read several posts on the Usenet about an alleged bug of the .NET platform that shows when dealing with SAFEARRAYs created via SafeArrayCreateVector(Ex) --this is far from confirmed, though. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

              K 1 Reply Last reply
              0
              • J Joaquin M Lopez Munoz

                Well, this is wild guessing, but anyway... What client technology are you using? If it's ASP or other VB-based stuff, seems like VBSCRIPT does not handle SAFEARRAYs of objects other than VARIANTs (read MSDN article PRB: Script Error Occurs When Referencing Non-variant Array (Q165967)). Also, if your client is written in C#, I've read several posts on the Usenet about an alleged bug of the .NET platform that shows when dealing with SAFEARRAYs created via SafeArrayCreateVector(Ex) --this is far from confirmed, though. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

                K Offline
                K Offline
                Krouer
                wrote on last edited by
                #7

                Client are currently in C++ (Console test app and ActiveX) I will give a try with SafeArrayCreateEx instead of SafeArrayCreateVectorEx. Perhaps, they have a bug with that last function. Many thanks Joaquin for your help, Thanks, Bruno

                J 1 Reply Last reply
                0
                • K Krouer

                  Client are currently in C++ (Console test app and ActiveX) I will give a try with SafeArrayCreateEx instead of SafeArrayCreateVectorEx. Perhaps, they have a bug with that last function. Many thanks Joaquin for your help, Thanks, Bruno

                  J Offline
                  J Offline
                  Joaquin M Lopez Munoz
                  wrote on last edited by
                  #8

                  Sorry I haven't been more helpful. Bonne chance! Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

                  K 1 Reply Last reply
                  0
                  • J Joaquin M Lopez Munoz

                    Sorry I haven't been more helpful. Bonne chance! Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

                    K Offline
                    K Offline
                    Krouer
                    wrote on last edited by
                    #9

                    Joaquín M López Muñoz wrote: Sorry I haven't been more helpful. Bonne chance! Don't be sorry. You have find the solution. I replace the SafeArrayCreateVectorEx by a SafeArrayCreateEx and it works perfectly. Gracias y buenas tardes, Bruno

                    J 1 Reply Last reply
                    0
                    • K Krouer

                      I have an automation interface which own a UDT array. The UDT is define as struct NoteDesc { float base; float pitch; float medium; }; In my interface, I have set the get and put properties. put works really great but after I return from get, I have memory crash in the kernel. Here my interface def: [ object, uuid(60C22F90-D3BB-4BA0-ABCC-837E4CA2AEF2), dual, helpstring("IScoreDesc Interface"), pointer_default(unique) ] interface IScoreDesc : IDispatch { [propget, id(1)] HRESULT NumberOfNote([out, retval] long *pVal); [propput, id(1)] HRESULT NumberOfNote([in] long newVal); [propget, id(2)] HRESULT Notes([out, retval] SAFEARRAY(NoteDesc) *pVal); [propput, id(2)] HRESULT Notes([in] SAFEARRAY(NoteDesc) newVal); }; and the class compil well, the call to get is effective. The problem occur when I return of the function get define like that in my h file: STDMETHOD(get_Notes)(SAFEARRAY* *pVal); Do you have any idea?

                      E Offline
                      E Offline
                      Ernest Laurentin
                      wrote on last edited by
                      #10

                      Try to declare the get property like this:

                      [propget, id(2)] HRESULT Notes([in,out] SAFEARRAY(NoteDesc) *pVal);

                      Define your UDT like this: Describing UDT in the IDL file

                      library ScoreDesc
                      {
                      // replace "C1D3A8C0-A4AA-11D0-819C-00A0C90FFFC3" by the correct one in your project
                      typedef [uuid(C1D3A8C0-A4AA-11D0-819C-00A0C90FFFC3)] struct_NoteDesc{
                      float base;
                      float pitch;
                      float medium
                      } NoteDesc;

                      or Take a look Passing UDT at MSDN - God bless the World

                      1 Reply Last reply
                      0
                      • K Krouer

                        Joaquín M López Muñoz wrote: Sorry I haven't been more helpful. Bonne chance! Don't be sorry. You have find the solution. I replace the SafeArrayCreateVectorEx by a SafeArrayCreateEx and it works perfectly. Gracias y buenas tardes, Bruno

                        J Offline
                        J Offline
                        Joaquin M Lopez Munoz
                        wrote on last edited by
                        #11

                        :-D!! Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

                        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