Как передать массив объектов (c# .net) в c++ (com)
От:
endri
Дата: 12.10.05 16:32
Оценка:
Господа.
Имеется класс, написанный на c#:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public class UserInfo
{
private int _userID = Null.NullInteger;
private int _groupID = Null.NullInteger;
private int _groupTypeID = Null.NullInteger;
[MarshalAs(UnmanagedType.BStr)]
private String _groupName = Null.NullString;
[MarshalAs(UnmanagedType.BStr)]
private String _firstName = Null.NullString;
[MarshalAs(UnmanagedType.BStr)]
private string _lastName = Null.NullString;
[MarshalAs(UnmanagedType.BStr)]
private string _username = Null.NullString;
[MarshalAs(UnmanagedType.BStr)]
private string _password = Null.NullString;
private bool _isSuperUser = Null.NullBoolean;
[MarshalAs(UnmanagedType.BStr)]
private string _universityName = Null.NullString;
}
Так же описан интерфейс для дальнейшего использования в com. В этом интерфейсе есть функция, возвращающая массив объектов UserInfo[].
В tlb формируется следующая структура:
typedef [uuid(8B077412-2955-3343-91FE-A2894BA5FF4F), version(1.0),
custom({0F21F359-AB84-41E8-9A78-36D110E6D2F9}, "NST.BLL.UserInfo" )
]
struct tagUserInfo {
long _userID;
long _groupID;
long _groupTypeID;
BSTR _groupName;
BSTR _firstName;
BSTR _lastName;
BSTR _username;
BSTR _password;
long _isSuperUser;
BSTR _universityName;
} UserInfo;
Функция, возвращающая массив выглядит так:
[id(0x60020003)]
HRESULT Users(
[in] long groupID,
[out, retval] SAFEARRAY(UserInfo*)* pRetVal);
Далее в с++ я подключаю com и выполняю следующие действия:
SAFEARRAY* psa;
pITestComponent->Users(1,&psa); // Users - функция, возвращающая массив UserInfo[]
UserInfo* pUserStruct = NULL; // UserInfo - структура, описанная в библиотеке типов(см. выше)
if (psa != NULL)
{
hr = SafeArrayAccessData(psa, (void **)&pUserStruct);
_ASSERT(SUCCEEDED(hr) && pUserStruct);
// здесь используем полученный массив структур pUserStruct, но он заполнен НЕ КОРРЕКТНО
hr = ::SafeArrayUnaccessData(psa);
_ASSERT(SUCCEEDED(hr));
}
SafeArrayDestroy(psa);
Проблема в том, что массив pUserStruct в последнем куске кода заполнен не правильно, всякой абракадаброй.
Подскажите, может я что не так делаю?
Заранее благодарю, Андрей.
Re: Как передать массив объектов (c# .net) в c++ (com)
От:
endri
Дата: 12.10.05 20:06
Оценка:
Кстати, можно добавить, что если передавать в COM не массив, а сам объект типа UserInfo, то всё нормально работает. Т.е. структрура типа UserInfo в с++ заполняется без проблем.
Re: Как передать массив объектов (c# .net) в c++ (com)
От:
Аноним
Дата: 12.10.05 22:27
Оценка:
Для просто unmanaged было так:
http://www.gotdotnet.ru/Forums/Common/135079.aspx , полное ли соотвествие для СОМ, перед сном не вспомню.
-----
Нулевое оформления постов благодаря Opere.
данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re[2]: Как передать массив объектов (c# .net) в c++ (com)
От:
endri
Дата: 13.10.05 13:18
Оценка:
Здравствуйте, AndroidLV, Вы писали:
ALV>Для просто unmanaged было так: http://www.gotdotnet.ru/Forums/Common/135079.aspx , полное ли соотвествие для СОМ, перед сном не вспомню.
Но это же передача массива структур из c++ DLL в .NET (C#). А мне наоборот нужно.
Re: Как передать массив объектов (c# .net) в c++ (com)
От:
GlebZ
Дата: 13.10.05 14:11
Оценка:
Здравствуйте, endri, Вы писали:
E>Проблема в том, что массив pUserStruct в последнем куске кода заполнен не правильно, всякой абракадаброй.
E>Подскажите, может я что не так делаю?
Попробуй получить через SafeArrayGetElement. Или лучше попробуй посмотреть SafeArrayElemsize. Может он тебе возвращает массив вариантов.
С уважением, Gleb.
Re[2]: Как передать массив объектов (c# .net) в c++ (com)
От:
Аноним
Дата: 13.10.05 14:16
Оценка:
Там в обе стороны описано:
http://www.gotdotnet.ru/Forums/Common/135079.aspx#135103 3. пункт заполнение pDataList перед вызовом.
-----
Нулевое оформления постов благодаря Opere.
данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re[3]: Как передать массив объектов (c# .net) в c++ (com)
От:
endri
Дата: 13.10.05 15:18
Оценка:
Здравствуйте, AndroidLV, Вы писали:
ALV>Там в обе стороны описано: http://www.gotdotnet.ru/Forums/Common/135079.aspx#135103 3. пункт заполнение pDataList перед вызовом.
Дело в том, что я пишу в среде c++ и с помощью COM Collable Wrapper подключаюсь к библиотеке, написанной на c#. В c++ я вызываю функцию, описанную в библиотеке типов (TLB), которая возвращает массив структур, формируемых как раз таки в библиотеке .NET.
Приведенный вами вариант мне не подходит, т.к. он нужен для работы в среде .net, с использованием в ней библиотек, написанных на c++. Никакого отношения к com-объектам они не имеют. В этом примере (3 пункт) формируется массив структур для передачи в сишные функции в качестве параметров.
Если я что-то не так понянимаю, поправте, пожалуйста.
Вопрос остается в силе.
С уважением, Андрей
Re[2]: Как передать массив объектов (c# .net) в c++ (com)
От:
endri
Дата: 13.10.05 15:21
Оценка:
Здравствуйте, GlebZ, Вы писали:
GZ>Попробуй получить через SafeArrayGetElement. Или лучше попробуй посмотреть SafeArrayElemsize. Может он тебе возвращает массив вариантов.
Пробовал через SafeArrayGetElement, ничего не вышло, та же беда. SafeArrayElemsize возвращает 4 (это видимо размер указателя на структуру типа UserInfo).
Re[3]: Как передать массив объектов (c# .net) в c++ (com)
От:
GlebZ
Дата: 13.10.05 15:46
Оценка:
Здравствуйте, endri, Вы писали:
E>Пробовал через SafeArrayGetElement, ничего не вышло, та же беда. SafeArrayElemsize возвращает 4 (это видимо размер указателя на структуру типа UserInfo).
Однако в твоем исходном сообщении стоит что это массив структур
UserInfo* pUserStruct = NULL; // UserInfo - структура, описанная в библиотеке типов(см. выше)
Попробуй сделать указатель на массив указателей на структуры
UserInfo** pUserStruct = NULL; // UserInfo - структура, описанная в библиотеке типов(см. выше)
С уважением, Gleb.
Re[4]: Как передать массив объектов (c# .net) в c++ (com)
От:
endri
Дата: 13.10.05 16:01
Оценка:
Здравствуйте, GlebZ, Вы писали:
GZ>Попробуй сделать указатель на массив указателей на структуры
GZ>GZ>UserInfo** pUserStruct = NULL; // UserInfo - структура, описанная в библиотеке типов(см. выше)
GZ>
Я не совсем понял что мне с этим указателем на массив делать дальше?
Заранее благодарю, Андрей.
Re[5]: Как передать массив объектов (c# .net) в c++ (com)
От:
GlebZ
Дата: 13.10.05 16:12
Оценка:
Здравствуйте, endri, Вы писали:
E>Здравствуйте, GlebZ, Вы писали:
GZ>>Попробуй сделать указатель на массив указателей на структуры
GZ>>GZ>>UserInfo** pUserStruct = NULL; // UserInfo - структура, описанная в библиотеке типов(см. выше)
GZ>>
E>Я не совсем понял что мне с этим указателем на массив делать дальше?
SAFEARRAY* psa;
pITestComponent->Users(1,&psa); // Users - функция, возвращающая массив UserInfo[]
UserInfo** pUserStruct = NULL; // UserInfo - структура, описанная в библиотеке типов(см. выше)
if (psa != NULL)
{
hr = SafeArrayAccessData(psa, (void **)&pUserStruct);
_ASSERT(SUCCEEDED(hr) && pUserStruct);
// здесь используем полученный массив структур pUserStruct, но он заполнен НЕ КОРРЕКТНО
long uBound;
long lBound;
hresult = SafeArrayGetUBound(psa, 1, &uBound);
if (FAILED(hresult))
return hresult;
hresult = SafeArrayGetLBound(psa, 1, &lBound);
if (FAILED(hresult))
return hresult;
for (long i=lBound;l<=uBound;l++)
MessageBoxW(NULL, (*pUserStruct)->_firstName, L"" , MB_OK);
hr = ::SafeArrayUnaccessData(psa);
_ASSERT(SUCCEEDED(hr));
}
SafeArrayDestroy(psa);
Так более понятно?
С уважением, Gleb.
Re[6]: Как передать массив объектов (c# .net) в c++ (com)
От:
endri
Дата: 13.10.05 16:19
Оценка:
Здравствуйте, GlebZ, Вы писали:
GZ>GZ>SAFEARRAY* psa;
GZ>pITestComponent->Users(1,&psa); // Users - функция, возвращающая массив UserInfo[]
GZ>UserInfo** pUserStruct = NULL; // UserInfo - структура, описанная в библиотеке типов(см. выше)
GZ>if (psa != NULL)
GZ>{
GZ> hr = SafeArrayAccessData(psa, (void **)&pUserStruct);
GZ> _ASSERT(SUCCEEDED(hr) && pUserStruct);
GZ> // здесь используем полученный массив структур pUserStruct, но он заполнен НЕ КОРРЕКТНО
GZ> long uBound;
GZ> long lBound;
GZ> hresult = SafeArrayGetUBound(psa, 1, &uBound);
GZ> if (FAILED(hresult))
GZ> return hresult;
GZ> hresult = SafeArrayGetLBound(psa, 1, &lBound);
GZ> if (FAILED(hresult))
GZ> return hresult;
GZ> for (long i=lBound;l<=uBound;l++)
GZ> MessageBoxW(NULL, (*pUserStruct)->_firstName, L"" , MB_OK);
GZ> hr = ::SafeArrayUnaccessData(psa);
GZ> _ASSERT(SUCCEEDED(hr));
GZ>}
GZ>SafeArrayDestroy(psa);
GZ>
Всё равно не работает. Структура заполнена неправильно. Все поля типа string = "Bad ptr".
Re[3]: Как передать массив объектов (c# .net) в c++ (com)
От:
Аноним
Дата: 13.10.05 20:37
Оценка:
Мне так показалось, что сам массив структур создается и возвращается из С#, если нет — сорри.
-----
Нулевое оформления постов благодаря Opere.
данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Пока на собственное сообщение не было ответов, его можно удалить.
Удалить