Interoperability(Interop)

상호운용성

unmanaged code에 대한 기존 투자를 보존하고 활용할 수 있게 한다.

즉 CLR을 사용하지 않는 어셈블리를 CLR에서 사용할 수 있게 만드는 것이다.

interop은 managed와 unmanaged를 오고가는 메모리 비용과 코드 작성 비용 때문에 최소화하는게 좋다.

 

COM Interop

Component Object Model(COM) 을 사용하면 개체의 기능을 다른 컴포넌트와 윈도우 플랫폼의 호스트 프로그램에 사용할 수 있다. 사용자가 기존 코드 베이스와 상호 운용할 수 있도록 .Net 프레임워크에서 COM라이브러리를 통해 interop을 지원한다.

 

Platform Invoke(P/Invoke)

P/Invoke는 사용자의 managed code에서 unmanaged 라이브러리의 구조, 콜백 그리고 기능에 접근할 수 있도록 한다. 대부분 P/Invoke API는 SystemSystem.Runtime.InteropServices 두 개의 네임스페이스를 포함한다.

이 두개의 네임스페이스를 사용하면 네이티브 컴포넌트를 사용할 수 있는 도구가 제공된다.

using System;
using System.Runtime.InteropServices;

public class Program
{
	// Import dll (containing the funtion)
    [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)
    // Define
    private static extern int MessageBox(IntPtr hWnd, string IpText, string IpCaption, uint uType);
    
    public static void Main(string[] args)
    {
    	// Invoke the function as a regular managed method
        MessageBox(IntPtr.Zero, "Command-line message box", "Attention!", 0);
    }
}
  1. Attribute
    • [DllImport] attribute은 런타임에 unmanaged DLL을 로드할것을 알린다.
    • "user32.dll" 문자열은 사용할 기능이 포함된 DLL을 대상으로 한다.
    • CharSet = CharSet.Unicode 문자열을 Mashalling하는데 사용할 문자 집합을 지정한다.
    • SetLastError = true 런타임에서 오류가 발생했을때 사용자가 Mashal.GetLastWin32Error()를 통해서 에러코드를 감지할 수 있게한다.
  2. Declare
    • 메서드 선언시 메서드명은 사용할 unmanaged code와 동일한 이름으로 작성한다.
    • 이때 extern 키워드를 통해서 해당 메서드가 외부의 메서드임을 런타임에 알린다.
    • 런타임은 외부 메서드라는것을 알게되면 해당 managed 메서드를 호출할 때 attribute의 설정을 통해 특정된 DLL을 찾아서 실행시킨다.
  3. Main method
    • managed code 즉 현재 작업중인 코드에서 extern으로 선언한 메서드를 호출하여 외부 메서드를 사용한다. 

 

Managed C++(C++/CLI)

Managed Extensions for C++ 또는 Managed C++은 문법적 그리고 구문적 확장, 키워드와 속성을 포함하고 C++의 구문 및 언어를 가져오는 .Net Framework의 C++ 언어 확장 집합이다. 이 확장자는 managed code상에서 C++ 코드가 CLR의 대상이 될 수 있도록 그리고 지속적으로 native code와 상호 운용될 수 있게하려고 마이크로소프트에서 만들었다.

 

2004년 Managed C++은 구문을 명확하고 단순화하고 managed generics을 포함하도록 기능을 크게 개선시켰다. 이렇게 새로운 확장자는 C++/CLI로 지정되었고 Visual Studio 2005 이후에 포함되면서 Managed C++을 대체하였다.

 

SWIG

Simplefied Wrapper and Interface Generator

C 또는 C++로 작성된 컴퓨터 프로그램이나 라이브러리 다른 프로그래밍 언어에서 사용할 수 있도록 연결하는데 사용하는 오픈소스 도구이다. 

주목적은 네이티브 함수의 호출, 복잡한 자료형을 함수에 전달, 메모리 부적절하게 해제하지 못하게 방지, 언어 간에 오브젝트 클래스를 상속할 수 있게 하는것이다.

728x90
반응형

extern

'외부의'라는 뜻을 가지는 External의 약자로 외부에 선언된 함수 또는 객체임을 명시하는 역할을 한다.

이때 외부란 C# 코드 이외의 언어로 작성된 코드를 뜻하며 DLL이나 C/C++ 등으로 작성된 함수를 말한다.

이런 외부에서 작성된 코드 즉, C# 및. Net 프레임 워크에서 사용되지 않는 코드 다시 말해서 CLR에서 관리되지 않는 코드를 unmanaged code라고 하는데 이러한 unmanaged code를 불러오기 위해서는 interop 기술이 필요하다.

 

Interop 정리글

 

간략하게 Interop은 다른 언어나 플랫폼에서 작성된 코드를 호출하거나 받는 기술로 COM, P/Invoke, C++/CLI 등이 대표적으로 있는데 extern 키워드는 이러한 함수나 객체가 외부의 것임을 나타내는 역할을 한다.

 

일반적으로 C#에서 많이 사용하는 P/Invoke 방식은 DllImport arttribute와 함께 사용한다.

이 경우 메서드는 반드시 static으로 선언되어야 한다.

// Microsoft AVI File support library
[DllImport("avifil32.dll")] // Interop, P/Invoke
private static extern void AVIFileInit();

 

extern alias

.Net 어셈블리에서 다른 버전의 동일한 어셈블리의 참조가 필요한 경우에 사용할 수 있다.

일반적으로 .Net 프로젝트에서 어셈블리의 참조는 using이나 Imports를 사용하여 참조하는데 만약 서로 다른 버전의 어셈블리를 참조하는 경우에는 컴파일러가 어떤 버전을 사용해야 하는지 구분이 필요하기 때문에 이런 경우 extern alias 키워드를 사용한다.

 

동일한 어셈블리를 버전별로 참조하기 위해서는 각각의 어셈블리를 특정시킬 수 있도록 만드는 작업이 필요하다.

특정시키는 방법으로는 각 어셈블리의 별칭을 지정하는 방법과 이름을 변경하는 방법이 있다.

 

Alias

어셈블리의 별칭을 지정하는 방법은 대표적으로 두 가지 방법이 있다.

 

1. Visual Studio 

비주얼 스튜디오의 솔루션 탐색기에서 별칭을 수정할 수 있다.

Assembly > 우클릭 속성 > Aliases 수정

2. 프롬프트 창

프롬프트에서 어셈블리에 별칭을 부여할 수 있다.

/r:GridV1=grid.dll
/r:GridV2=grid20.dll

 

각각의 어셈블리에 외부에서 사용할 별칭 GridV1과 GridV2가 지정된다.

 

이렇게 별칭을 지정해 주면 extern 키워드를 사용하여 별칭을 참조하면 동일한 어셈블리를 구분해서 참조가 가능해진다.

extern alias GridV1;
extern alias GridV2;
// can using namespace
using Class1V1 = GridV1::Namespace.Class1;
using Class1V2 = GridV2::Namespace.Class1;

 

Name

별칭을 지정하지 않고 이름을 변경하는 방법으로도 참조가 가능하다.

비주얼 스튜디오에서 별칭을 수정했던 설정창을 다시 켜보면 상단에 이름 속성을 확인할 수 있다.

이름을 사용하기 위해서는 별칭이 지정되지 않아야 하므로 별칭을 지우고 이름을 수정한다.

 

그 후에 C#에서 Type.GetType 메서드를 사용하면 어셈블리에서 Type을 가져올 수 있는데 이때 어셈블리의 전체 이름을 사용하여 Type을 가져오면 해당 어셈블리를 특정해서 참조할 수 있게 된다.

Type myType = Type.GetType("MyNamespace.MyType, MyAssembly");

 

728x90
반응형

'Program Language > C#' 카테고리의 다른 글

Interoperability  (0) 2023.02.02
Managed, Unmanaged, Native Code  (0) 2023.02.02
C# 키워드 : delegate, event, action  (0) 2023.01.31
C# 상수 키워드 : const  (0) 2023.01.31
C# 비동기화 키워드 : async, await  (0) 2023.01.31

+ Recent posts