Приветствую всех.
У меня есть компонент в виде dll в которой описаны типы данных похожие на эти:
// midl code
typedef [uuid(...)] struct CITEM
{
long data;
} CITEM;
// эта структура содержит массив структур типа CITEM
typedef [uuid(...)] struct CDATA
{
long id;
SAFEARRAY (CITEM) Items;
} CDATA;
Эти описанные типы я использую в разных компонентах (VB и VC) путём подключения dll. В одном из этих компонентов есть метод, который принимает CDATA в качестве параметра по ссылке (или по значению). Проблема в том, что если этот компонент реализован как exe сервер, то возникает ошибка 800703E6 ("Invalid access to memory location"). Если же компонент реализован как in-proc, то все работает Ok. Может кто знает как побороть эту ошибку. Буду благодарен.
ICQ #311116826
Re: Проблема с передачей массивов UDT в exe сервер
хъ
МА>Эти описанные типы я использую в разных компонентах (VB и VC) путём подключения dll. В одном из этих компонентов есть метод, который принимает CDATA в качестве параметра по ссылке (или по значению). Проблема в том, что если этот компонент реализован как exe сервер, то возникает ошибка 800703E6 ("Invalid access to memory location"). Если же компонент реализован как in-proc, то все работает Ok. Может кто знает как побороть эту ошибку. Буду благодарен.
приведи описание на idl метода, где возникает ошибка
Re[2]: Проблема с передачей массивов UDT в exe сервер
Структура пакуется в Variant. Может есть какие атрибуты midl для передачи массивов?
В VB это вызов выглядит так:
Public Sub TestResCtrl()
Dim cClsExe As New tstClsExe 'это ехе сервер
Dim cClsDll As New tstClsDll 'это in-proc
Dim sTst As STSTENDLib.CDATA 'создаем и инитим структуры
ReDim sTst.Items(0) As STSTENDLib.CITEM
sTst.Items(0).UCI = 1
sTst.Items(0).NControl = 1
' send command
Dim v
Dim id As Long
v = CVar(sTst)
id = 42
tstClsDll.Command id, v 'тут работает
tstClsExe.Command id, v <<<<< тут ошибка :crash:
End Sub
ICQ #311116826
Re[3]: Проблема с передачей массивов UDT в exe сервер
Здравствуйте Алекс, Вы писали:
А>тут не указано направление параметров. Как действует oleaut32.dll в таких случаях мне не известно. Поставь лучше явно in.
Public Sub TestResCtrl()
Dim cClsExe As New tstClsExe 'это ехе сервер
Dim cClsDll As New tstClsDll 'это in-proc
Dim sTst As STSTENDLib.CDATA 'создаем и инитим структуры
'ReDim sTst.Items(0) As STSTENDLib.CITEM ' если здесь закоментарить, то все работает :xz:
' sTst.Items(0).UCI = 1
' sTst.Items(0).NControl = 1
' send command
Dim v
Dim id As Long
v = CVar(sTst)
id = 42
tstClsDll.Command id, v 'тут работает
tstClsExe.Command id, v <<<<< тут ошибка :crash:
End Sub
ICQ #311116826
Re[5]: Проблема с передачей массивов UDT в exe сервер
Здравствуйте Максим Алексейкин, Вы писали:
МА>Здравствуйте Алекс, Вы писали:
А>>тут не указано направление параметров. Как действует oleaut32.dll в таких случаях мне не известно. Поставь лучше явно in.
МА>Не помогло
кстати!
Как это ты преобразовываешь UDT в VARIANT? нет такого кастинга!
Re[6]: Проблема с передачей массивов UDT в exe сервер
Здравствуйте Алекс, Вы писали:
А>кстати! А>Как это ты преобразовываешь UDT в VARIANT? нет такого кастинга!
Если тип описан в ActiveX контроле (его библиотеке типов), то его можно упаковать в Variant. Только описан он должен быть с атрибутом uuid, иначе не выйдет.
ICQ #311116826
Re[7]: Проблема с передачей массивов UDT в exe сервер
Здравствуйте Максим Алексейкин, Вы писали:
МА>Здравствуйте Алекс, Вы писали:
А>>кстати! А>>Как это ты преобразовываешь UDT в VARIANT? нет такого кастинга!
МА>Если тип описан в ActiveX контроле (его библиотеке типов), то его можно упаковать в Variant. Только описан он должен быть с атрибутом uuid, иначе не выйдет.
ну не знаю на счет запаковки в VARIANT, а отмаршалируется он точно криво.
Re[8]: Проблема с передачей массивов UDT в exe сервер
Жмотишься, и тексты не показываешь, прям клещами нужно вытаскивать!
МА>Эти описанные типы я использую в разных компонентах (VB и VC) путём подключения dll. В одном из этих компонентов есть метод, который принимает CDATA в качестве параметра по ссылке (или по значению).
МА>Проблема в том, что если этот компонент реализован как exe сервер, то возникает ошибка 800703E6 ("Invalid access to memory location").
Я так понимаю, что EXE сервер твой так вываливается.
МА>Если же компонент реализован как in-proc, то все работает Ok. Может кто знает как побороть эту ошибку. Буду благодарен.
Вот и покажи, как ты принимаешь эти параметры. И как точно в IDL описан сам интерфейс и этот метод, а также структура(ы).
Скорее всего ты принимаешь на входе не верную информацию. Да, и что приходит на входе в метод на сервере?
Здравствуйте Максим Алексейкин, Вы писали:
МА>Здравствуйте Максим Алексейкин, Вы писали:
МА>>Скорее всего это и происходит Ща попробую без запаковки.
МА>Попробовал МА>Теперь в сообщении вместо 800703E6 стоит C0000005. В общем тотже доступ к памяти.
код приведи
Re[11]: Проблема с передачей массивов UDT в exe сервер
Да код по сути тотже. У меня на VB зделаны in-proc и out-proc сервера. К их проектам подключена dll в которой описаны типы данных. Тестовый метод простейший:
Public Sub Test (p As CDATA)
MsgBox CStr(p.id)
End Sub
В клиенте:
Public Sub TestResCtrl()
Dim cClsExe As New tstClsExe 'это ехе сервер
Dim cClsDll As New tstClsDll 'это in-proc
Dim sTst As STSTENDLib.CDATA 'создаем и инитим структуры
ReDim sTst.Items(0) As STSTENDLib.CITEM
sTst.Items(0).UCI = 1
sTst.Items(0).NControl = 1
tstClsDll.Test sTst 'тут работает
tstClsExe.Test sTst <<<<< тут ошибка :crash:
End Sub
ICQ #311116826
Re[2]: Проблема с передачей массивов UDT в exe сервер
STDMETHODIMP CSrvManager::Command(long SysId, VARIANT *Data)
{
SYSTEMS::iterator it = m_Systems.find ( SysId );
PSYS pSys;
if ( it != m_Systems.end() )
{
pSys = it->second;
// тут переадресуем вызов нужному in-proc объекту
if ( (CProtocolControl*)pSys )
pSys->Command ( Data );
}else if ( m_dwLogMask & PU_COMMAND ) {
// ругаемся в лог
}
}
return S_OK;
}
А это клиент:
Public Sub ResCtrl ()
Dim SMng As New SrvManager
Dim sTst As CRESCTRL
ReDim sTst.Items(0 To 0) As CRESCTRLITM
sTst.Items(0).UCI = 1
sTst.Items(0).NCtrl = 1
' send command
Dim v
Dim id As Long
v = sTst
id = 42
SMng.Command id, v ' тут все и заканчивается. в сервер вызов не доходит
End Sub
Здравствуйте Максим Алексейкин, Вы писали:
МА>typedef [uuid(2779091F-9AF1-463f-8C88-F4611E6C01BF)] struct CRESCTRLITM МА>{ МА> short UCI; МА> short NCtrl; МА>} CRESCTRLITM; МА>typedef [uuid(FC72D445-9E5A-4b74-89AE-C8FD28F5BCAC)] struct CRESCTRL МА>{ МА> short PackIdent; МА> [in, ref] SAFEARRAY (CRESCTRLITM) Items; МА>} CRESCTRL;
Кажется выяснил как побороть. Если структура CRESCTRLITM содержит хотябы один элемент размером 4 байта (BSTR, long), то всё работает на ура. Т.е. надо переписать так:
typedef [uuid(2779091F-9AF1-463f-8C88-F4611E6C01BF)] struct CRESCTRLITM
{
long UCI;
long NCtrl;
} CRESCTRLITM;
и всё будет работать. Видимо это связано с каким-нибудь выравниванием данных при маршалинге. О чём MS "забыла" предупредить остальной мир или скромно умолчала.
ICQ #311116826
Re[4]: Проблема с передачей массивов UDT в exe сервер
Здравствуйте Максим Алексейкин, Вы писали:
МА>Здравствуйте Максим Алексейкин, Вы писали:
хъ
МА>Кажется выяснил как побороть. Если структура CRESCTRLITM содержит хотябы один элемент размером 4 байта (BSTR, long), то всё работает на ура. Т.е. надо переписать так: МА>
МА>typedef [uuid(2779091F-9AF1-463f-8C88-F4611E6C01BF)] struct CRESCTRLITM
МА>{
МА> long UCI;
МА> long NCtrl;
МА>} CRESCTRLITM;
МА>
МА>и всё будет работать. Видимо это связано с каким-нибудь выравниванием данных при маршалинге. О чём MS "забыла" предупредить остальной мир или скромно умолчала.