Подскажите что не так делаю (Маршалинг + UNION в структуре)
От: a_yenzh  
Дата: 12.11.06 18:36
Оценка:
Подскажите пожалуйста новичку, что не так делаю

Есть С-ая функция:
 BOOL sprPeekMessage(HANDLE Handle, LPSPRECORDMESSAGE lpMessage, LPDWORD lpdwSize);

в которую передается структура с union:
typedef struct _SPRECORDMESSAGE {
    DWORD cbSize;
    SYSTEMTIME MsgTime;
    DWORD dwMsgType;
    union {
      RECORDSTART RecordStart;
      NEWRING NewRing;
      ANIDETECT ANIDetected;
      RECORDRINGTYPE RecordRingType;
      NEWOUTPHONE NewOutPhone;
      ANIDETECT SkippedPhoneNumber;
      RECORDSTOP RecordStop;
      NEWCHANNELNAME NewChannelName;
      char cbStr[SPRECORD_MAXTEXTSIZE + 1];
    };
  } SPRECORDMESSAGE, *PSPRECORDMESSAGE, *LPSPRECORDMESSAGE;


Пробовал вызывать эту функцию делать 2-мя вариантами:
[StructLayout(LayoutKind.Sequential)]
public struct SpRecordMessage
{
public int Size;
    public DateTime MsgTime;
    public int MsgType;            
    public EventType ev;    
    //public IntPtr info;        
}

[StructLayout(LayoutKind.Explicit)]        
public struct EventType
{        
[ FieldOffset( 0 )]
public RecordStart recordStart;
    [ FieldOffset( 0 )]
    public NewRing newRing;
    [ FieldOffset( 0 )]
    public ANIDetect aniDetected;            
    [ FieldOffset( 0 )]
    public RecordRingType recordRingType;            
    [ FieldOffset( 0 )]
    public NewOutPhone newOutPhone;            
    [ FieldOffset( 0 )]
    public ANIDetect skipedPhoneNumber;            
    [ FieldOffset( 0 )]
    public RecordStop recordStop;            
    [ FieldOffset( 0 )]
    public NewChanelName newChanelName;            
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=4079),FieldOffset( 0 )]
    public String cbStr;            
}    

[DllImport("spclient.DLL", EntryPoint="sprPeekMessage")]        
public static extern bool sprPeekMessage(int Handle, ref SpRecordMessage spRecordMessage, int Size);

И собственно вызов:
SpRecordMessage Msg;
Msg=new SpRecordMessage();
Msg.ev.RecordStart.ChannelName="";
Msg.ev.RecordStart.FileName="";
Msg.ev.RecordStart.PhoneNumber="";
Msg.ev.RecordStart.RingType=0;

// EventType ev=new EventType();
// ev.RecordStart.ChannelName="";
// ev.RecordStart.FileName="";
// ev.RecordStart.PhoneNumber="";
// ev.RecordStart.RingType=0;
// IntPtr buffer = Marshal.AllocCoTaskMem( Marshal.SizeOf( ev ));
// Marshal.StructureToPtr( ev, buffer, false );
// spMsg.info=buffer;

sprPeekMessage(ConnectionHandle, ref Msg,Marshal.SizeOf(Msg))    
//sprPeekMessage(ConnectionHandle, ref Msg,Marshal.SizeOf(Msg)+ //Marshal.SizeOf(ev))

в результате ошибка: “Object reference not set to an instance of an object”.


Подскажите плз или где можно почитать. И можно ли вообще сделать такой “анонимный” аналог union в С#

Всем спасибо !!!
Подскажите что не так делаю (Маршалинг + UNION в структуре)
От: Аноним  
Дата: 13.11.06 02:23
Оценка:
посмотри этот пример может пригодицо.
--------------
Любое удобство идет за счет мегагерцеф! : {<b>1</b>, <b>2</b>, <b>3</b>, 4}


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re: Подскажите что не так делаю (Маршалинг + UNION в структу
От: a_yenzh  
Дата: 13.11.06 06:28
Оценка:
Здравствуйте, Nimnul, Вы писали:

N>посмотри этот пример может пригодицо.


N>
данное сообщение получено с www.gotdotnet.ru

N>ссылка на оригинальное сообщение


уже видел
не помогло че делать уже не знаю
Re: Подскажите что не так делаю (Маршалинг + UNION в структу
От: Аноним  
Дата: 13.11.06 06:51
Оценка:
покажи как ты пробывал на основе данного примера.
--------------
Любое удобство идет за счет мегагерцеф! : {<b>1</b>, <b>2</b>, <b>3</b>, 4}


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re[2]: Подскажите что не так делаю (Маршалинг + UNION в стру
От: ZeeM  
Дата: 13.11.06 06:59
Оценка:
Здравствуйте, Nimnul, Вы писали:

N>покажи как ты пробывал на основе данного примера.


N>
данное сообщение получено с www.gotdotnet.ru

N>ссылка на оригинальное сообщение


У меня такая же проблема с этими unionami. Пока получилось только "в лоб" сделать. Т.е. в зависимости от типа структура в unione формировать ее соответствующим образом. И вручную ставить размер максимальной. Но это не выход.

Пример тоже видел. Но как побороть то что все структуры в unione начинаются с одного адреса? Тут без Fieloffseta не обойтись. А если его использовать то в итоге ряд экзепшенов хватаешь.
Re[3]: Подскажите что не так делаю (Маршалинг + UNION в стру
От: Аноним  
Дата: 13.11.06 09:02
Оценка:
Здравствуйте, ZeeM, Вы писали:

ZM>Здравствуйте, Nimnul, Вы писали:


N>>покажи как ты пробывал на основе данного примера.


N>>
данное сообщение получено с www.gotdotnet.ru

N>>ссылка на оригинальное сообщение


ZM>У меня такая же проблема с этими unionami. Пока получилось только "в лоб" сделать. Т.е. в зависимости от типа структура в unione формировать ее соответствующим образом. И вручную ставить размер максимальной. Но это не выход.


ZM>Пример тоже видел. Но как побороть то что все структуры в unione начинаются с одного адреса? Тут без Fieloffseta не обойтись. А если его использовать то в итоге ряд экзепшенов хватаешь.


Неужели никто не работал с unioнами? Решение в лоб очень некрасивое. А при попытке сделать так как в шапке летит экзепшн

Could not load type 'Dispatcher.UnionStruct' from assembly 'Dispatcher, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 0 that is incorrectly aligned or overlapped by a non-object field.
Re[4]: Подскажите что не так делаю (Маршалинг + UNION в стру
От: Codechanger Россия  
Дата: 13.11.06 09:31
Оценка:
Здравствуйте, Аноним, Вы писали:

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


ZM>>Здравствуйте, Nimnul, Вы писали:


N>>>покажи как ты пробывал на основе данного примера.


N>>>
данное сообщение получено с www.gotdotnet.ru

N>>>ссылка на оригинальное сообщение


ZM>>У меня такая же проблема с этими unionami. Пока получилось только "в лоб" сделать. Т.е. в зависимости от типа структура в unione формировать ее соответствующим образом. И вручную ставить размер максимальной. Но это не выход.


ZM>>Пример тоже видел. Но как побороть то что все структуры в unione начинаются с одного адреса? Тут без Fieloffseta не обойтись. А если его использовать то в итоге ряд экзепшенов хватаешь.


А>Неужели никто не работал с unioнами? Решение в лоб очень некрасивое. А при попытке сделать так как в шапке летит экзепшн


А>Could not load type 'Dispatcher.UnionStruct' from assembly 'Dispatcher, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 0 that is incorrectly aligned or overlapped by a non-object field.


IntPtr передаешь и не паришься.
Re[5]: Подскажите что не так делаю (Маршалинг + UNION в стру
От: ZeeM  
Дата: 13.11.06 09:50
Оценка:
Здравствуйте, Codechanger, Вы писали:

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


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


ZM>>>Здравствуйте, Nimnul, Вы писали:


N>>>>покажи как ты пробывал на основе данного примера.


N>>>>
данное сообщение получено с www.gotdotnet.ru

N>>>>ссылка на оригинальное сообщение


ZM>>>У меня такая же проблема с этими unionami. Пока получилось только "в лоб" сделать. Т.е. в зависимости от типа структура в unione формировать ее соответствующим образом. И вручную ставить размер максимальной. Но это не выход.


ZM>>>Пример тоже видел. Но как побороть то что все структуры в unione начинаются с одного адреса? Тут без Fieloffseta не обойтись. А если его использовать то в итоге ряд экзепшенов хватаешь.


А>>Неужели никто не работал с unioнами? Решение в лоб очень некрасивое. А при попытке сделать так как в шапке летит экзепшн


А>>Could not load type 'Dispatcher.UnionStruct' from assembly 'Dispatcher, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 0 that is incorrectly aligned or overlapped by a non-object field.


C>IntPtr передаешь и не паришься.


Так дело в том что мне и так необходимо передавать указатель на массив байт в котором содержится структура.

Т.е. вместо каждой структуры, содержащейся в unione ты также предлагаешь вставлять указатель?
Re[5]: Подскажите что не так делаю (Маршалинг + UNION в стру
От: a_yenzh  
Дата: 13.11.06 11:56
Оценка:
Здравствуйте, Codechanger, Вы писали:
C>IntPtr передаешь и не паришься
Пробовал у меня же во втором варианте (закоментаренном ) так и есть
выделяю память и IntPtr на нее (поле info)
но та же ошибка Object reference not set to an instance of an object

а по поводу ошибки
Could not load type 'Dispatcher.UnionStruct' from assembly 'Dispatcher, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 0 that is incorrectly aligned or overlapped by a non-object field.
просто получается что нельзя в структуре с указанием OffSet применять и value и ref types по крайней мере в Framework
v 1.1
Re[6]: Подскажите что не так делаю (Маршалинг + UNION в стру
От: Аноним  
Дата: 13.11.06 13:26
Оценка:
Здравствуйте, a_yenzh, Вы писали:

_>Здравствуйте, Codechanger, Вы писали:

C>>IntPtr передаешь и не паришься
_>Пробовал у меня же во втором варианте (закоментаренном ) так и есть
_>выделяю память и IntPtr на нее (поле info)
_>но та же ошибка Object reference not set to an instance of an object

_>а по поводу ошибки

_>Could not load type 'Dispatcher.UnionStruct' from assembly 'Dispatcher, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 0 that is incorrectly aligned or overlapped by a non-object field.
_>просто получается что нельзя в структуре с указанием OffSet применять и value и ref types по крайней мере в Framework
_>v 1.1

И еще — в unione будет содержаться указатель, который занимает 4 байта. В результате в union приходят некорректные данные.
Re[7]: Подскажите что не так делаю (Маршалинг + UNION в стру
От: a_yenzh  
Дата: 13.11.06 14:53
Оценка:
А>И еще — в unione будет содержаться указатель, который занимает 4 байта. В результате в union приходят некорректные данные.

Так а как сделать тогда анонимный union?
Re[8]: Подскажите что не так делаю (Маршалинг + UNION в стру
От: a_yenzh  
Дата: 13.11.06 21:17
Оценка:
вопрос закрыт.

ошибка была не там где искал
но аналога анонимности добился :


[StructLayout(LayoutKind.Explicit)]
public struct SpRecordMessage
{
    [ FieldOffset( 0 )]
    public int Size;
    [ FieldOffset( 4 )]
    public DateTime MsgTime;
    [ FieldOffset( 20 )]
    public int MsgType;            
    [ FieldOffset( 24 )]
    public NewRing newRing;
    [ FieldOffset( 24 )]
    public ANIDetect aniDetected;            
    [ FieldOffset( 24 )]
    public RecordRingType recordRingType;            
    [ FieldOffset( 24 )]
    public NewOutPhone newOutPhone;            
    [ FieldOffset( 24 )]
    public ANIDetect skipedPhoneNumber;            
    [ FieldOffset( 24 )]
    public RecordStop recordStop;            
    [ FieldOffset( 24 )]
    public NewChanelName newChanelName;            
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=4079),FieldOffset( 24 )]
    public String cbStr;        
}

т.е. не вынося в отдельную структуру
Re[5]: Подскажите что не так делаю (Маршалинг + UNION в стру
От: Аноним  
Дата: 14.11.06 01:51
Оценка:
Видимо ты еще мало попарился с маршалингом раз невнемлишь моим словам
--------------
Любое удобство идет за счет мегагерцеф! : {<b>1</b>, <b>2</b>, <b>3</b>, 4}


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re[9]: Поясни плиз.
От: ZeeM  
Дата: 14.11.06 07:26
Оценка:
Здравствуйте, a_yenzh, Вы писали:

_>вопрос закрыт.


_>ошибка была не там где искал

_>но аналога анонимности добился :


_>
_>[StructLayout(LayoutKind.Explicit)]
_>public struct SpRecordMessage
_>{
_>    [ FieldOffset( 0 )]
_>    public int Size;
_>    [ FieldOffset( 4 )]
_>    public DateTime MsgTime;
_>    [ FieldOffset( 20 )]
_>    public int MsgType;            
_>    [ FieldOffset( 24 )]
_>    public NewRing newRing;
_>    [ FieldOffset( 24 )]
_>    public ANIDetect aniDetected;            
_>    [ FieldOffset( 24 )]
_>    public RecordRingType recordRingType;            
_>    [ FieldOffset( 24 )]
_>    public NewOutPhone newOutPhone;            
_>    [ FieldOffset( 24 )]
_>    public ANIDetect skipedPhoneNumber;            
_>    [ FieldOffset( 24 )]
_>    public RecordStop recordStop;            
_>    [ FieldOffset( 24 )]
_>    public NewChanelName newChanelName;            
_>    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=4079),FieldOffset( 24 )]
_>    public String cbStr;        
_>}

_>

_>т.е. не вынося в отдельную структуру

А сами структуры, которые содержатся в unione ты как описываешь? Т.е. используя FieldOffset или нет?
И еще — получалось ли нормально получать указатель на такую структуру, содержащую union?
Re[6]: Подскажите что не так делаю (Маршалинг + UNION в стру
От: a_yenzh  
Дата: 14.11.06 09:42
Оценка:
Здравствуйте, Nimnul, Вы писали:

N>Видимо ты еще мало попарился с маршалингом раз невнемлишь моим словам

Так и есть. Это мой первый опыт.
А что значит невнемлю? имеется ввиду что я не использую IntPtr с выделением памяти через Marshal? Так я так тоже пробовал но разницы не заметил.

ZeeM
структуры внутри юниона с атрибутом [StructLayout(LayoutKind.Sequential)]
но можно и FieldOffset но только главное чтобы не перекрывались поля структур разных типов (ref и value)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.