Safearray of UDT
-
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?
-
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?
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 -
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 DesarrolloThe 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
-
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
The only thing I can guess about your code is that maybe
sizeof(NoteDesc)
is not equal to the value provided bypRecordInfo->GetSize()
due to alignment considerations. Could you check that out? Joaquín M López Muñoz Telefónica, Investigación y Desarrollo -
The only thing I can guess about your code is that maybe
sizeof(NoteDesc)
is not equal to the value provided bypRecordInfo->GetSize()
due to alignment considerations. Could you check that out? Joaquín M López Muñoz Telefónica, Investigación y DesarrolloThe 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
-
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
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
SAFEARRAY
s of objects other thanVARIANT
s (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 withSAFEARRAY
s created viaSafeArrayCreateVector
(Ex
) --this is far from confirmed, though. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo -
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
SAFEARRAY
s of objects other thanVARIANT
s (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 withSAFEARRAY
s created viaSafeArrayCreateVector
(Ex
) --this is far from confirmed, though. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo -
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
Sorry I haven't been more helpful. Bonne chance! Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
-
Sorry I haven't been more helpful. Bonne chance! Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
-
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?
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
-
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
:-D!! Joaquín M López Muñoz Telefónica, Investigación y Desarrollo