C#에서 C++이나 VB로 된 DLL을 Interop해서 쓰는 방식이 .NET으로 전환하는 요즘의 대세이건만

언제나 그 반대의 경우도 존재하게 마련이다.

 

C#에서는 Typelib를 tlbimp해서 dll을 참조하는 방법과

dllimport Attribute를 이용해서 dll을 참조하는 방법이 있는데

보통 typelib는 COM이나 ActiveX 형태의 dll을, dllimport는 extern이나 static으로

외부로 인터페이스를 제공하는 dll을 참조하는 경우이다.

 

이와달리, 이전글에서 C++에서 C# DLL을 호출하는 경우는

기존의 legacy 시스템에서 .NET의 특수한 기능(가령, Remoting이나 COM+ 등)을 이용하려는 경우

유용하게 쓰일수 있다.

 

앞글에서 설명한 요점을 살펴보면

1. C#으로 필요한 기능을 구현한다. 이때 dll은 COM으로 등록시킨다.

그러기 위해서 외부로 노출시킬 Interface를 생성하여 이를 상속받는 클래스를

생성한 후, GUID를 부여해야한다.

2. 생성된 C# dll을 regasm으로 등록하고 이때 생성된 *.tlb파일을 C++에서 import하고

Interface를 통해 클래스의 메소드를 호출한다.

 

요게 다구나..

 

비즈니스 로직이 C# DLL에 있는 경우에는 내부적으로 필요한 라이브러리들을

호출하여 이용하겠지만,

만약, C++ 코드에서 C#의 Class들을 이용해야 할 경우 mscorlib.tlb를 import하면

C++에서 C#의 클래스들을 이용할 수 있다.

---------------------------------------------------------------------------------------

[C#예제]

 

[Guid("11111111-1111-1111-1111-111111111111")]

public Interface ICSharpInterface

{

void CallCSharpMethod(string s);

}

 

[Guid("22222222-2222-2222-2222-222222222222")]

public class CSharpClass : ICSharpInterface

{

public void CallCSharpMethod(string s)

{

MessageBox.Show(s);

}

}

--------------------------------------------------------------------------------------

[C++ 예제]

#include "CSharpClass.tlb" no_namespace named_guids

 

ICSharpInterface *csi = NULL;
CoInitialize(NULL);
HRESULT hr = CoCreateInstance(CLSID_CSharpClass,
NULL, CLSCTX_INPROC_SERVER, IID_ICSharpInterface, reinterpret_cast<void**>(&csi));

if (FAILED(hr))
{
printf("C# interface Initialize failed!");
CoUninitialize();
return FALSE;
}

 

try {
csi->CallCSharpMethod("인자값");
} catch (_com_error &e) {
printf("C# Method call error!");
return FALSE;
}

 

csi->Release();
CoUninitialize();
csi = NULL;

--------------------------------------------------------------------------------------

C# 예제를 컴파일하고

c:\>regasm CSharpClass.dll /tlb:CSharpClass.tlb

로 등록한다.

 

생성된 CSharpClass.tlb를 C++ 프로젝트 폴더에 두고 컴파일한다.

 

생성된 C++ 실행파일을 실행하면 C#의 Method가 Call되어 메시지박스가 호출된다

 

+ Recent posts