Атрибут MarshalAs задает правила передачи параметров, наиболее часто он используется в следующих видах:
• MarshalAs(UnmanagedType.LPWStr)– Unicode-строка. Память под строку распределяется и освобождается через системные функции.
• MarshalAs(UnmanagedType.LPArray, SizeParamIndex=n)– передается одномерный массив, размер массива задается параметром с номером n, нумерация параметров начинается с нуля.
• MarshalAs(UnmanagedType.Interface)– передается COM интерфейс.
Примеры интерфейсов
IDL
[object, uuid(0002E000-0000-0000-C000-000000000046), pointer_default(unique)]
interface IEnumGUID : IUnknown {
HRESULT Next([in] ULONG celt,
[out, size_is(celt), length_is(*pceltFetched)] GUID *rgelt,
[out] ULONG *pceltFetched);
HRESULT Skip([in] ULONG celt);
HRESULT Reset();
HRESULT Clone([out] IEnumGUID **ppenum);
}
[object, uuid(0002E011-0000-0000-C000-000000000046), pointer_default(unique)]
interface IEnumCATEGORYINFO : IUnknown {
HRESULT Next([in] ULONG celt,
[out, size_is(celt), length_is(*pceltFetched)] CATEGORYINFO *rgelt,
[out] ULONG *pceltFetched);
HRESULT Skip([in] ULONG celt);
HRESULT Reset();
HRESULT Clone([out] IEnumCATEGORYINFO **ppenum);
}
[object, uuid(0002E013-0000-0000-C000-000000000046), pointer_default(unique)]
interface ICatInformation : IUnknown {
HRESULT EnumCategories([in] LCID lcid,
[out] IEnumCATEGORYINFO** ppenumCategoryInfo);
HRESULT GetCategoryDesc([in] REFCATID rcatid,
[in] LCID lcid,
[out] LPWSTR* pszDesc);
[local]
HRESULT EnumClassesOfCategories([in] ULONG cImplemented,
[in,size_is(cImplemented)] CATID rgcatidImpl[],
[in] ULONG cRequired,
[in,size_is(cRequired)] CATID rgcatidReq[],
[out] IEnumCLSID** ppenumClsid);
[call_as(EnumClassesOfCategories)]
HRESULT RemoteEnumClassesOfCategories([in] ULONG cImplemented,
[in,unique,size_is(cImplemented)] CATID rgcatidImpl[],
[in] ULONG cRequired,
[in,unique,size_is(cRequired)] CATID rgcatidReq[],
[out] IEnumCLSID** ppenumClsid);
[local]
HRESULT IsClassOfCategories([in] REFCLSID rclsid,
[in] ULONG cImplemented,
[in,size_is(cImplemented)] CATID rgcatidImpl[],
[in] ULONG cRequired,
[in,size_is(cRequired)] CATID rgcatidReq[]);
[call_as(IsClassOfCategories)]
HRESULT RemoteIsClassOfCategories([in] REFCLSID rclsid,
[in] ULONG cImplemented,
[in,unique,size_is(cImplemented)] CATID rgcatidImpl[],
[in] ULONG cRequired,
[in,unique,size_is(cRequired)] CATID rgcatidReq[]);
HRESULT EnumImplCategoriesOfClass([in] REFCLSID rclsid,
[out] IEnumCATID** ppenumCatid);
HRESULT EnumReqCategoriesOfClass([in] REFCLSID rclsid,
[out] IEnumCATID** ppenumCatid);
}
C#
[ComImport, Guid("0002E000-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IEnumGUID {
[PreserveSig()]
int Next([In] uint celt,
[Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] Guid[] rgelt,
[Out] out uint pceltFetched);
[PreserveSig()]
int Skip([In] uint celt);
void Reset();
[return : MarshalAs(UnmanagedType.Interface)]
IEnumGUID Clone();
};
[ComImport, Guid("0002E011-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IEnumCATEGORYINFO {
[PreserveSig()]
int Next([In] uint celt,
[Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] CATEGORYINFO[] rgelt,
[Out] out uint pceltFetched);
[PreserveSig()]
int Skip([In] uint celt);
void Reset();
[return : MarshalAs(UnmanagedType.Interface)]
IEnumCATEGORYINFO Clone();
};
[ComImport, Guid("0002E013-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ICatInformation {
[return : MarshalAs(UnmanagedType.Interface)]
IEnumCATEGORYINFO EnumCategories([In] uint lcid);
[return : MarshalAs(UnmanagedType.LPWStr)]
String GetCategoryDesc([In] ref Guid rcatid, [In] uint lcid);
[return : MarshalAs(UnmanagedType.Interface)]
IEnumGUID EnumClassesOfCategories([In] uint cImplemented,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] Guid[] rgcatidImpl,
[In] uint cRequired,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=2)] Guid[] rgcatidReq);
[return : MarshalAs(UnmanagedType.Interface)]
IEnumGUID RemoteEnumClassesOfCategories([In] uint cImplemented,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] Guid[] rgcatidImpl,
[In] uint cRequired,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=2)] Guid[] rgcatidReq);
[PreserveSig()]
int IsClassOfCategories([In] ref Guid rclsid,
[In] uint cImplemented,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] Guid[] rgcatidImpl,
[In] uint cRequired,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=2)] Guid[] rgcatidReq);
[PreserveSig()]
int RemoteIsClassOfCategories([In] ref Guid rclsid,
[In] uint cImplemented,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] Guid[] rgcatidImpl,
[In] uint cRequired,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=2)] Guid[] rgcatidReq);
[return : MarshalAs(UnmanagedType.Interface)]
IEnumGUID EnumImplCategoriesOfClass([In] ref Guid rclsid);
[return : MarshalAs(UnmanagedType.Interface)]
IEnumGUID EnumReqCategoriesOfClass([In] ref Guid rclsid);
};
Описание классов
Для описания классов также используются атрибуты ComImport и Guid. Классы с атрибутом ComImport не могут иметь никаких данных и методов.
Пример описания класса
IDL
Описание отсутствует
C#
[ComImport, Guid("0002E005-0000-0000-C000-000000000046")]
Читать дальше