HOW TO:手動建立包裝函式
如果您決定在 Managed 原始程式碼中以手動方式宣告 COM 型別,要開始的最佳位置是使用現有的介面定義語言 (IDL) 檔案或型別程式庫。 如果您沒有 IDL 檔案或無法產生型別程式庫檔案,可以透過建立 Managed 宣告及匯出產生的組件,來模擬 COM 型別。
若要從 Managed 原始程式碼模擬 COM 型別
在與 Common Language Specification (CLS) 相容的語言中宣告型別,並編譯檔案。
使用型別程式庫匯出工具 (Tlbexp.exe) 來匯出含有型別的組件。
使用匯出的 COM 型別程式庫做為宣告 COM 導向之 Managed 型別的基礎。
若要建立執行階段可呼叫包裝函式 (RCW)
假設您有一個 IDL 檔案或型別程式庫檔案,請決定哪些類別或介面要包含在自訂 RCW 中。 您可以排除任何不打算在應用程式中直接或間接使用的型別。
在 符合 CLS 標準的語言中建立原始程式檔,並宣告型別。 請參閱型別程式庫至組件轉換的摘要,以取得匯入轉換過程的完整說明。 實際上,當建立自訂的 RCW 時,您是以手動方式執行型別程式庫匯入工具 (Tlbimp.exe) 所提供的型別轉換活動。 遵循此程序的範例顯示 IDL 或型別程式庫檔中的型別,以及在 C# 程式碼中對應的型別。
完成宣告後請編譯檔案,如同您編譯任何其他 Managed 原始程式碼一樣。
與使用 Tlbimp.exe 匯入的型別一樣,有些型別需要您可以直接加入程式碼中的其他資訊。 如需詳細資訊,請參閱 HOW TO:編輯 Interop 組件。
範例
下列程式碼顯示 IDL 中的 ISATest 介面和 SATest 類別以及 C# 原始程式碼中的對應型別的範例。
IDL 或型別程式庫檔案
[
object,
uuid(40A8C65D-2448-447A-B786-64682CBEF133),
dual,
helpstring("ISATest Interface"),
pointer_default(unique)
]
interface ISATest : IDispatch
{
[id(1), helpstring("method InSArray")]
HRESULT InSArray([in] SAFEARRAY(int) *ppsa, [out,retval] int *pSum);
};
[
uuid(116CCA1E-7E39-4515-9849-90790DA6431E),
helpstring("SATest Class")
]
coclass SATest
{
[default] interface ISATest;
};
Managed 原始程式碼中的包裝函式
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
[assembly:Guid("E4A992B8-6F5C-442C-96E7-C4778924C753")]
[assembly:ImportedFromTypeLib("SAServerLib")]
namespace SAServer
{
[ComImport]
[Guid("40A8C65D-2448-447A-B786-64682CBEF133")]
[TypeLibType(TypeLibTypeFlags.FLicensed)]
public interface ISATest
{
[DispId(1)]
//[MethodImpl(MethodImplOptions.InternalCall,
// MethodCodeType=MethodCodeType.Runtime)]
int InSArray( [MarshalAs(UnmanagedType.SafeArray,
SafeArraySubType=VarEnum.VT_I4)] ref int[] param );
}
[ComImport]
[Guid("116CCA1E-7E39-4515-9849-90790DA6431E")]
[ClassInterface(ClassInterfaceType.None)]
[TypeLibType(TypeLibTypeFlags.FCanCreate)]
public class SATest : ISATest
{
[DispId(1)]
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType=MethodCodeType.Runtime)]
extern int ISATest.InSArray( [MarshalAs(UnmanagedType.SafeArray,
SafeArraySubType=VarEnum.VT_I4)] ref int[] param );
}
}