방법: 수동으로 래퍼 만들기
관리되는 소스 코드에서 사용자가 직접 COM 형식을 선언하려는 경우에는 기존의 IDL(인터페이스 정의 언어) 파일이나 형식 라이브러리에서 시작하는 것이 좋습니다. IDL 파일이 없거나 형식 라이브러리 파일을 만들 수 없는 경우에는 관리되는 선언을 만든 다음 결과로 생성된 어셈블리를 형식 라이브러리로 내보내서 COM 형식을 시뮬레이션할 수 있습니다.
관리되는 소스에서 COM 형식을 시뮬레이션하려면
CLS(공용 언어 사양) 규격의 언어로 형식을 선언한 다음 해당 파일을 컴파일합니다.
형식 라이브러리 내보내기(Tlbexp.exe)를 사용하여 해당 형식이 포함된 어셈블리를 내보냅니다.
내보낸 COM 형식 라이브러리를 기본으로 사용하여 COM 기반의 관리되는 형식을 선언합니다.
RCW(런타임 호출 가능 래퍼)를 만들려면
IDL 파일 또는 형식 라이브러리 파일이 있는 경우, 사용자 지정 RCW에 포함시킬 클래스 및 인터페이스를 결정합니다. 응용 프로그램에서 직접 또는 간접적으로 사용하지 않을 형식은 제외시킬 수 있습니다.
CLS 규격의 언어로 소스 파일을 만든 다음 해당 형식을 선언합니다. 가져오기 변환 프로세스에 대한 자세한 내용은 형식 라이브러리를 어셈블리로 변환 요약을 참조하십시오. 사실, 사용자 지정 RCW를 만드는 것은 형식 라이브러리 가져오기(Tlbimp.exe)에서 제공하는 형식 변환 작업을 수동으로 수행하고 있는 것과 같습니다. 이 절차 뒤에 나오는 예제에서는 IDL 또는 형식 라이브러리 파일에 있는 형식과 C# 코드에서 이 형식에 해당하는 형식을 보여 줍니다.
선언이 완료되면 다른 관리되는 소스 코드를 컴파일할 때와 마찬가지로 파일을 컴파일합니다.
Tlbimp.exe를 사용하여 가져온 형식과 마찬가지로 일부 경우에는 추가 정보가 필요하여, 이는 사용자가 코드에 직접 추가할 수 있습니다. 자세한 내용은 방법: 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;
};
관리되는 소스 코드의 래퍼
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 );
}
}