// MyUDT as defined in the server.
[Guid("190A418D-B113-40d4-A22C-20EF9EAC3E33")]
[StructLayout(LayoutKind.Sequential)]
struct MyUDT
{
[MarshalAs(UnmanagedType.BStr)]
public string aBstr;
public int aLong;
public bool aBool;
}
如下所示定义 COM 接口:
// A possible C# representation of the interface.
[InterfaceType(ComInterfaceType.InterfaceIsDual),
Guid("78D4F391-B10B-4B80-A2D1-1B4C583DCAEC")]
interface IComArrsObj
{
void GetArrOfLongs(int startIdx, ref int cnt, out IntPtr arrAddr);
void GetArrOfUDTs (int startIdx, ref int cnt, out IntPtr arrAddr);
void MyNextLongs (int req,
[MarshalAs(UnmanagedType.LPArray, Out]
int [ ] rgelt,
out int fetched);
void MyNextUDTs (int req,
[MarshalAs(UnmanagedType.LPArray, Out]
MyUDT [ ] rgelt,
out int fetched);
}
如下所示定义 COM 服务器:
// The coclass.
[ComImport, Guid("056A32CF-D716-4902-BCD2-ED7F070D9E36")]
class CComArrsObj
{
}
如下所示在 COM 服务器上调用方法:
public static void Run ( )
{
Console.WriteLine ( "\nTesting C#-declared COM class and interfaces:" );
Console.WriteLine ( "============================================:" );
Console.WriteLine ( "Creating COM object" );
ComArrs_0.IComArrsObj icao = new ComArrs_0.CComArrsObj ( )
as ComArrs_0.IComArrsObj;
Console.WriteLine ( "Calling GetArrOfLongs( )" );
int cnt = 0;
IntPtr rAddr;
icao.GetArrOfLongs ( 0, ref cnt, out rAddr );
int [ ] r = new int [ cnt ];
// Marshal the array from an unmanaged to a managed heap.
Marshal.Copy ( rAddr, r, 0, cnt );
// Release the unmanaged array.
Marshal.FreeCoTaskMem ( rAddr );
Utils.PrintArray ( r, elementFormatter );
Console.WriteLine ( "Calling GetArrOfUDTs( )" );
cnt = 0;
IntPtr ruAddr;
icao.GetArrOfUDTs ( 0, ref cnt, out ruAddr );
ComArrs_0.MyUDT [ ] ru = new ComArrs_0.MyUDT [ cnt ];
// Marshal the array, element by element, from an unmanaged to a managed heap.
for ( int i = 0, elemOffs = (int) ruAddr; i < cnt; i++ )
{
ru[i] = ( ComArrs_0.MyUDT ) Marshal.PtrToStructure (
(IntPtr) elemOffs, typeof ( ComArrs_0.MyUDT ) );
elemOffs += Marshal.SizeOf ( typeof ( ComArrs_0.MyUDT ) );
}
// Release the unmanaged array.
Marshal.FreeCoTaskMem ( ruAddr );
Utils.PrintArray ( ru, elementFormatter );
Console.WriteLine ( "Calling MyNextLongs( )" );
int [ ] q = new int [20];
// The marshalling is performed automatically.
icao.MyNextLongs ( q.GetLength(0), q, out cnt );
Utils.PrintArray ( q, elementFormatter );
Console.WriteLine ( "Calling MyNextUDTs( )" );
ru = new ComArrs_0.MyUDT [20];
// The marshalling is performed automatically.
icao.MyNextUDTs ( ru.GetLength(0), ru, out cnt );
Utils.PrintArray ( ru, elementFormatter );
}
class MgdComArrs
{
public MgdComArrs ( )
{ cao_ = new ComArrs_1.CComArrsObj( ); }
public int [ ] GetArrOfLongs ( int startIdx, ref int cnt )
{
IntPtr rAddr;
cao_.GetArrOfLongs ( startIdx, ref cnt, out rAddr );
int [ ] r = new int [ cnt ];
// Marshal the array from an unmanaged to a managed heap.
Marshal.Copy ( rAddr, r, 0, cnt );
// Release the unmanaged array.
Marshal.FreeCoTaskMem ( rAddr );
return r;
}
public ComArrs_1.MyUDT [ ] GetArrOfUDTs ( int startIdx, ref int cnt )
{
IntPtr ruAddr;
cao_.GetArrOfUDTs ( startIdx, ref cnt, out ruAddr );
ComArrs_1.MyUDT [ ] ru = new ComArrs_1.MyUDT [ cnt ];
// Marshal the array, element by element.
for ( int i = 0, elemOffs = (int) ruAddr; i < cnt; i++ )
{
ru[i] = (ComArrs_1.MyUDT) Marshal.PtrToStructure (
(IntPtr) elemOffs, typeof ( ComArrs_1.MyUDT ) );
elemOffs += Marshal.SizeOf ( typeof ( ComArrs_1.MyUDT ) )'
}
// Release the unmanaged array.
Marshal.FreeCoTaskMem ( ruAddr );
return ru;
}
public int MyNextLongs ( int req, int [ ] r )
{
int fetched;
cao_.MyNextLongs ( req, r, out fetched );
return fetched;
}
public int MyNextUDTs ( int req, ComArrs_1.MyUDT [ ] r )
{
int fetched;
cao_.MyNextUDTs ( req, r, out fetched );
return fetched;
}
private ComArrs_1.CComArrsObj cao_;
}