Re: SafeArray и struct. Как создать массив структур?
От: DNS Россия  
Дата: 17.10.01 11:15
Оценка:
Здравствуйте Romsky, Вы писали:

R>У меня вопрос перекликающийся со многими из данного форума и все же я его задам :)

R>Как создать массив структур в C++ для передачи его по DCOM-у?
R>С описаниями в IDL проблем нет. Проблема приего создании с помощью SafeArrayCreate. А по функции SafeArrayCreateEx доку найти не могу :(.
R>Помогите кто знает как это сделать!!!

Вот пример из MSDN:

Passing Safearray of UDTs
For passing a safearrray of UDTs, the designer of the server describes the data types of the UDT in a IDL file. The client needs the type library to fetch the IRecordInfo Interface. The safearray is then created with SafeArrayCreateEx. The following is the IDL for a safearray of UDTs to be passed:

library Student
{
importlib("stdole2.tlb");
typedef enum tagclassification {school_Bully, class_Clown, teachers_Favorite} classification;
typedef [uuid(D8B3861A-74C6-11d2-A0D6-00C04FB17CDB)] struct tagStudentStruct {
        BSTR name;
        short grade;
        classification  type;
        VARIANT_BOOL    graduate;
} StudentStruct;
[
object,
uuid(D50BD660-7471-11d2-9A80-006097DA88F5),            // IID_IStudent
helpstring("User Defined Data Server"),
dual,
pointer_default(unique)
]
interface IStudent : IDispatch
{
import "unknwn.idl";
typedef IStudent* LPSTUDENT;

HRESULT Test2([in,out] SAFEARRAY(StudentStruct));
};


For passing a safearray of UDTs the type library is necessary for fetching the IRecordInfo Interface. The type library of the UDT is first loaded by calling LoadRegTypeLib and the type information of the UDT is obtained with GetTypeInfoOfGuid. The GetRecordInfoFromTypeInfo function is then called to obtain the record information from the type information of the UDT. At this point the record information is returned to pRecInfo.

LPTYPEINF pTypeInfo = NULL;
LPTYPELIB pTypelib = NULL;
LPSAFEARRAY psaStudent = NULL;
SAFEARRAYBOUND rgbounds = { 4, 0 };
StudentStruct *pStudentStruct = NULL;
IRecordInfo* pRecInfo = NULL;

// Fetch the IRecordInfo interface describing the UDT
hr = LoadRegTypeLib(LIBID_Student, 1, 0, GetUserDefaultLCID(), &pTypelib);
hr = pTypelib->GetTypeInfoOfGuid(UUID_StudentStruct, &pTypeInfo);
_ASSERT(SUCCEEDED(hr) && pTypeInfo);
hr = GetRecordInfoFromTypeInfo(pTypeInfo, &pRecInfo);
_ASSERT(SUCCEEDED(hr) && pRecInfo);
RELEASEINTERFACE(pTypeInfo);
RELEASEINTERFACE(pTypelib);


Once pRecInfo is obtained from the type library, SafeArrayCreateEx is called to create the safearray, where its last parameter is pRecInfo. SafeArrayAccessData is then called to increment the lock count of the array.

psaStudent = SafeArrayCreateEx(VT_RECORD, 1, &rgbounds, pRecInfo);
RELEASEINTERFACE(pRecInfo);
_ASSERT(psaStudent);
hr = SafeArrayAccessData(psaStudent, reinterpret_cast<PVOID*>(&pStudentStruct));
_ASSERT(SUCCEEDED(hr) && pStudentStruct);


Then the StudentStruct safearray of UDTs is declared and assigned some values:

pStudentStruct[0].grade = 3;
pStudentStruct[0].name = SysAllocString(L"Shaun");
pStudentStruct[0].type = class_Clown;
pStudentStruct[1].grade = 8;
pStudentStruct[1].name = SysAllocString(L"Fred");
pStudentStruct[1].type = school_Bully;
pStudentStruct[2].grade = 12;
pStudentStruct[2].name = SysAllocString(L"Steve");
pStudentStruct[2].type = teachers_Favorite;
pStudentStruct[3].grade = 3;
pStudentStruct[3].name = SysAllocString(L"Linda");
pStudentStruct[3].type = teachers_Favorite;


SafeArrayUnaccessData is then called to decrement the lock count of the array, and invalidates the pointer retrieved by SafeArrayAccessData:
hr = SafeArrayUnaccessData(psaStudent);
_ASSERT(SUCCEEDED(hr));


The safearray is then passed to the Test2 method:

hr = pStudent->Test2(psaStudent);
Д.Н.С.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.