Проблема с передачей массивов UDT в exe сервер
От: Максим Алексейкин Россия  
Дата: 24.09.02 11:40
Оценка:
Приветствую всех.
У меня есть компонент в виде 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 сервер
От: Алекс Россия http://wise-orm.com
Дата: 24.09.02 11:43
Оценка:
Здравствуйте Максим Алексейкин, Вы писали:

хъ

МА>Эти описанные типы я использую в разных компонентах (VB и VC) путём подключения dll. В одном из этих компонентов есть метод, который принимает CDATA в качестве параметра по ссылке (или по значению). Проблема в том, что если этот компонент реализован как exe сервер, то возникает ошибка 800703E6 ("Invalid access to memory location"). Если же компонент реализован как in-proc, то все работает Ok. Может кто знает как побороть эту ошибку. Буду благодарен.


приведи описание на idl метода, где возникает ошибка
Re[2]: Проблема с передачей массивов UDT в exe сервер
От: Максим Алексейкин Россия  
Дата: 24.09.02 11:49
Оценка:
Здравствуйте Алекс, Вы писали:
[...]

interface ISrvManager : IDispatch
{
   [id(1)] HRESULT Command(long SysId, VARIANT *Data);
   ...
};

Структура пакуется в 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 сервер
От: Алекс Россия http://wise-orm.com
Дата: 24.09.02 12:10
Оценка:
Здравствуйте Максим Алексейкин, Вы писали:

МА>Здравствуйте Алекс, Вы писали:

МА>[...]

МА>
МА>interface ISrvManager : IDispatch
МА>{
МА>   [id(1)] HRESULT Command(long SysId, VARIANT *Data);
МА>   ...
МА>};
МА>


тут не указано направление параметров. Как действует oleaut32.dll в таких случаях мне не известно. Поставь лучше явно in.
Re[4]: Проблема с передачей массивов UDT в exe сервер
От: Максим Алексейкин Россия  
Дата: 24.09.02 12:36
Оценка:
Здравствуйте Алекс, Вы писали:

А>тут не указано направление параметров. Как действует oleaut32.dll в таких случаях мне не известно. Поставь лучше явно in.


Не помогло
ICQ #311116826
Re[3]: Небольшое уточнение
От: Максим Алексейкин Россия  
Дата: 24.09.02 12:44
Оценка:
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 сервер
От: Алекс Россия http://wise-orm.com
Дата: 24.09.02 13:03
Оценка:
Здравствуйте Максим Алексейкин, Вы писали:

МА>Здравствуйте Алекс, Вы писали:


А>>тут не указано направление параметров. Как действует oleaut32.dll в таких случаях мне не известно. Поставь лучше явно in.


МА>Не помогло


кстати!

Как это ты преобразовываешь UDT в VARIANT? нет такого кастинга!
Re[6]: Проблема с передачей массивов UDT в exe сервер
От: Максим Алексейкин Россия  
Дата: 24.09.02 13:11
Оценка:
Здравствуйте Алекс, Вы писали:

А>кстати!

А>Как это ты преобразовываешь UDT в VARIANT? нет такого кастинга!

Если тип описан в ActiveX контроле (его библиотеке типов), то его можно упаковать в Variant. Только описан он должен быть с атрибутом uuid, иначе не выйдет.
ICQ #311116826
Re[7]: Проблема с передачей массивов UDT в exe сервер
От: Алекс Россия http://wise-orm.com
Дата: 24.09.02 13:16
Оценка:
Здравствуйте Максим Алексейкин, Вы писали:

МА>Здравствуйте Алекс, Вы писали:


А>>кстати!

А>>Как это ты преобразовываешь UDT в VARIANT? нет такого кастинга!

МА>Если тип описан в ActiveX контроле (его библиотеке типов), то его можно упаковать в Variant. Только описан он должен быть с атрибутом uuid, иначе не выйдет.


ну не знаю на счет запаковки в VARIANT, а отмаршалируется он точно криво.
Re[8]: Проблема с передачей массивов UDT в exe сервер
От: Максим Алексейкин Россия  
Дата: 24.09.02 13:23
Оценка:
Здравствуйте Алекс, Вы писали:

А>ну не знаю на счет запаковки в VARIANT, а отмаршалируется он точно криво.


Скорее всего это и происходит Ща попробую без запаковки.
ICQ #311116826
Re[9]: Проблема с передачей массивов UDT в exe сервер
От: Максим Алексейкин Россия  
Дата: 24.09.02 13:29
Оценка:
Здравствуйте Максим Алексейкин, Вы писали:

МА>Скорее всего это и происходит Ща попробую без запаковки.


Попробовал
Теперь в сообщении вместо 800703E6 стоит C0000005. В общем тотже доступ к памяти.
ICQ #311116826
Re: Проблема с передачей массивов UDT в exe сервер
От: Vi2 Удмуртия http://www.adem.ru
Дата: 24.09.02 13:32
Оценка:
Здравствуйте Максим Алексейкин, Вы писали:

Жмотишься, и тексты не показываешь, прям клещами нужно вытаскивать!

МА>Эти описанные типы я использую в разных компонентах (VB и VC) путём подключения dll. В одном из этих компонентов есть метод, который принимает CDATA в качестве параметра по ссылке (или по значению).


МА>Проблема в том, что если этот компонент реализован как exe сервер, то возникает ошибка 800703E6 ("Invalid access to memory location").


Я так понимаю, что EXE сервер твой так вываливается.

МА>Если же компонент реализован как in-proc, то все работает Ok. Может кто знает как побороть эту ошибку. Буду благодарен.


Вот и покажи, как ты принимаешь эти параметры. И как точно в IDL описан сам интерфейс и этот метод, а также структура(ы).
Скорее всего ты принимаешь на входе не верную информацию. Да, и что приходит на входе в метод на сервере?
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[10]: Проблема с передачей массивов UDT в exe сервер
От: Алекс Россия http://wise-orm.com
Дата: 24.09.02 13:34
Оценка:
Здравствуйте Максим Алексейкин, Вы писали:

МА>Здравствуйте Максим Алексейкин, Вы писали:


МА>>Скорее всего это и происходит Ща попробую без запаковки.


МА>Попробовал

МА>Теперь в сообщении вместо 800703E6 стоит C0000005. В общем тотже доступ к памяти.

код приведи
Re[11]: Проблема с передачей массивов UDT в exe сервер
От: Максим Алексейкин Россия  
Дата: 24.09.02 13:41
Оценка:
Здравствуйте Алекс, Вы писали:

А>код приведи


Да код по сути тотже. У меня на 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 сервер
От: Максим Алексейкин Россия  
Дата: 24.09.02 13:59
Оценка:
Здравствуйте Vi2, Вы писали:
[...]

Вот показываю. Но сразу хочу сказать, что до сервера дело не доходит. Вываливается на уровне системы, видимо при маршалинге.

Это Idl:
[...]
interface ISrvManager : IDispatch
{
[id(1)] HRESULT Command([in] long SysId, [in, ref] VARIANT *Data);
[id(2)] HRESULT Connect(long SysId, BSTR Password);
[id(3)] HRESULT Disconnect(long SysId);
[propget, id(4)] HRESULT CurState(long SysId, [out, retval] long *pVal);
[propget, id(5)] HRESULT IsRuleSupervised(long sysId, long uci, long nctrl, [out, retval] VARIANT_BOOL *pVal);
};

library OMEGAPUSERVERLib
{
 ...
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;
 ...
[...]
coclass SrvManager
{
[default] interface ISrvManager;
interface IMngrControl;
};
}

Это сервер:
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
ICQ #311116826
Re[3]: А что внутри [...]?
От: Vi2 Удмуртия http://www.adem.ru
Дата: 24.09.02 14:16
Оценка:
Здравствуйте Максим Алексейкин, Вы писали:

МА>Это Idl:

МА>[...]
МА>interface ISrvManager : IDispatch
МА>{


Вот тут подробней о параметрах внутри [...].
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[4]: А что внутри [...]?
От: Максим Алексейкин Россия  
Дата: 24.09.02 14:22
Оценка:
Здравствуйте Vi2, Вы писали:
Vi2>Здравствуйте Максим Алексейкин, Вы писали:
МА>>Это Idl:
МА>>[...]
МА>>interface ISrvManager : IDispatch
МА>>{

Vi2>Вот тут подробней о параметрах внутри [...].

[
object,
uuid(38B5E06B-A4A4-47DB-B351-82E3654C5890),
dual,
helpstring("ISrvManager Interface"),
pointer_default(unique)
]
ICQ #311116826
Re[3]: А зачем здесь [in, ref] ?
От: Vi2 Удмуртия http://www.adem.ru
Дата: 24.09.02 14:23
Оценка:
Здравствуйте Максим Алексейкин, Вы писали:

МА>typedef [uuid(FC72D445-9E5A-4b74-89AE-C8FD28F5BCAC)] struct CRESCTRL

МА>{
МА> short PackIdent;
МА> [in, ref] SAFEARRAY (CRESCTRLITM) Items;
МА>} CRESCTRL;

А зачем здесь [in, ref] ? А если убрать?
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[5]: А oleautomation?
От: Vi2 Удмуртия http://www.adem.ru
Дата: 24.09.02 14:26
Оценка:
Здравствуйте Максим Алексейкин, Вы писали:

МА>[
МА>object,
МА>uuid(38B5E06B-A4A4-47DB-B351-82E3654C5890),
МА>dual,
МА>helpstring("ISrvManager Interface"),
МА>pointer_default(unique)
МА>]


Попробуй добавить object,oleautomation,dual. От того, что он dual или что он от IDispatch наследуется — это ничего никому не говорит.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[4]: А зачем здесь [in, ref] ?
От: Максим Алексейкин Россия  
Дата: 24.09.02 14:31
Оценка:
Здравствуйте Vi2, Вы писали:

Vi2>Здравствуйте Максим Алексейкин, Вы писали:


МА>>typedef [uuid(FC72D445-9E5A-4b74-89AE-C8FD28F5BCAC)] struct CRESCTRL

МА>>{
МА>> short PackIdent;
МА>> [in, ref] SAFEARRAY (CRESCTRLITM) Items;
МА>>} CRESCTRL;

Vi2>А зачем здесь [in, ref] ? А если убрать?


Это уже мой глюк. Появился в процессе поиска решений изначально тут ничего не было.
ICQ #311116826
Re[3]: Проблема с передачей массивов UDT в exe сервер
От: Максим Алексейкин Россия  
Дата: 25.09.02 08:47
Оценка:
Здравствуйте Максим Алексейкин, Вы писали:

МА>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 сервер
От: Алекс Россия http://wise-orm.com
Дата: 25.09.02 09:02
Оценка:
Здравствуйте Максим Алексейкин, Вы писали:

МА>Здравствуйте Максим Алексейкин, Вы писали:


хъ

МА>Кажется выяснил как побороть. Если структура CRESCTRLITM содержит хотябы один элемент размером 4 байта (BSTR, long), то всё работает на ура. Т.е. надо переписать так:

МА>
МА>typedef [uuid(2779091F-9AF1-463f-8C88-F4611E6C01BF)] struct CRESCTRLITM
МА>{ 
МА>   long UCI;
МА>   long NCtrl;
МА>} CRESCTRLITM;
МА>

МА>и всё будет работать. Видимо это связано с каким-нибудь выравниванием данных при маршалинге. О чём MS "забыла" предупредить остальной мир или скромно умолчала.

тогда используй
#pragma pack(4)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.