Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как получить из COM сервера структуру по двойной ссылке

49K
22 октября 2012 года
Nik531
8 / / 08.10.2009
есть COM сервер у него есть метод

 
Код:
virtual  HRESULT STDMETHODCALLTYPE GetInfo(/* [out] */ INFO **ppInfo) = 0;
структура в С++ определена так

Код:
typedef /* [public][public][public] */
enum __MIDL___MIDL_itf_hae_0000_0001
    {   UP  = 1,
    DOWN    = 2
    }   STATUS;

typedef /* [public][public] */ struct __MIDL___MIDL_itf_hae_0000_0003
    {
    FILETIME ftTime_1;
    FILETIME ftTime_2;
    STATUS Status;
    DWORD dwReturnRecords;
    WORD wCount;
    WORD wCount2;
    WORD wCount3;
    /* [string] */ LPWSTR szStatusString;
    /* [string] */ LPWSTR szInfo;
    }   INFO;
в C# реализуется клиент взывающий данный метод. Метод описан как
 
Код:
void GetInfo(out IntPtr ppInfo);
Структура определена так


Код:
internal enum HAE_SERVER_STATUS
    {  
            HAE_UP  = 1,
        HAE_DOWN
    }
 
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    internal struct INFO
    {
        public System.Runtime.InteropServices.ComTypes.FILETIME ftTime_1;
        public System.Runtime.InteropServices.ComTypes.FILETIME ftTime_2;
        STATUS Status;
        [MarshalAs(UnmanagedType.I4)]
    public int dwReturnRecords;
        [MarshalAs(UnmanagedType.I2)]
        public short wCount;
        [MarshalAs(UnmanagedType.I2)]
        public short wCount2;
        [MarshalAs(UnmanagedType.I2)]
        public short wCount3;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string szStatusString;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string szVendor;
     }
ну и сам вызов

 
Код:
INFO pftStatus = new INFO();
IntPtr lpstruct = MarshalToPointer(pftStatus);
IntPtr lppstruct = MarshalToPointer(lpstruct);
server.GetInfo(out lppstruct);
pftStatus = (INFO)MarshalToStruct(lpstruct, typeof(INFO));
дополнительные функции

Код:
private IntPtr MarshalToPointer(object data)
{
    IntPtr buf = Marshal.AllocHGlobal(Marshal.SizeOf(data));
        Marshal.StructureToPtr(data, buf, false);
        return buf;
}

private object MarshalToStruct(IntPtr buf, Type t)
{
    return Marshal.PtrToStructure(buf, t);
}
структура в итоге получается пустая. Как правильно вызывать данный метод ?
49K
22 октября 2012 года
Nik531
8 / / 08.10.2009
надо было добавить выравнивание в 1 байт
Код:
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
    internal struct INFO
    {
        public System.Runtime.InteropServices.ComTypes.FILETIME ftTime_1;
        public System.Runtime.InteropServices.ComTypes.FILETIME ftTime_2;
        public STATUS Status;
        [MarshalAs(UnmanagedType.I4)]
        public int dwReturnRecords;
        [MarshalAs(UnmanagedType.I2)]
        public short wCount;
        [MarshalAs(UnmanagedType.I2)]
        public short wCount2;
        [MarshalAs(UnmanagedType.I2)]
        public short wCount3;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string szStatusString;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string szVendor;
     }
и тогда сам вызов упрощается.
 
Код:
IntPtr lppStatus;
server.GetInfo(out lppStatus);
INFO pStatus = new INFO();
pStatus = (INFO)Marshal.PtrToStructure(lppStatus, typeof(INFO));
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог