블로그 이미지
대갈장군

calendar

1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

Notice

2013. 4. 13. 05:34 프로그래밍/MSDN

요즘 작업중인 프로젝트는 C++/CLI를 이용한 몇개의 프로젝트인데 중간 중간 C# 폼이 사용된다. 물론 Managed code와 Unmanaged code (Native code)를 함께 사용하기 위해서는 C++/CLI를 사용해야 한 다는 것 쯤은 나도 알고 있지만 왜 그럴까에 대한 진지한 생각은 해본적이 없다.


Stackoverflow 사이트를 돌아다니다 보니 좋은 글이라고 링크해 놓았길래 한번 번역해본다.


출처 - http://msdn.microsoft.com/en-us/magazine/dd315414.aspx


1. 언제 Managed-Native Interop이 사용되어야 하는가?

뭐 주절주절 써놓았는데 중간에 딱 한 문단이 마음에 확 와닿는다. 


These three applications address the three most common reasons to use interop: to allow managed extensibility of preexisting native applications, to allow most of an application to take advantage of the benefits of managed code while still writing the lowest-level pieces in native code, and to add a differentiated, next-generation user experience to an existing native application.


세가지 예시를 들면서 언제가 Managed 코드와 Native 코드를 섞어서 쓰는게 좋은가에 대해서 설명한 다음에 위와 같이 정의했다. 


"이러한 세가지 어플리케이션은 interop (Managed code와 Native code를 섞어쓰는 것을 말함)를 사용하는 가장 흔한 세가지 이유를 나타낸다: 원래 존재하던 native 어플리케이션에 managed 확장 가능성을 허락해 주는 것이 첫째이고, 둘째는 native 코드의 저레벨 코딩을 계속 쓰면서 동시에 managed code의 이점을 취할 수 있는 것이고, 마지막으로 셋째는 현존하는 native 어플리케이션에 차별화된, 또는 차세대 사용자 경험을 추가할 수 있기 때문이다."


영어를 한국어로 번역하다보면 적절한 한국어 찾기가 뜻을 이해하는 것보다 훨씬 더 어렵다. 젠장. 


2. Interop Technologies: 세가지 경우


There are three main interop technologies available in the .NET Framework, and which one you choose will be determined in part by the type of API you are using for interop and in part by your requirements and need to control the boundary. Platform Invoke, or P/Invoke, is primarily a managed-to-native interop technology that allows you to call C-style native APIs from managed code. COM interop is a technology that allows you either to consume native COM interfaces from managed code or export native COM interfaces from managed APIs. Finally there is C++/CLI (formerly known as managed C++), which allows you to create assemblies that contain a mix of managed and native C++ compiled code and is designed to serve as a bridge between managed and native code.


.NET 프레임워크에서는 세가지의 interop 기술들이 사용가능한데 다음과 같다.

첫째는 Platform Invoke 혹은 P/Invoke라고 불리는 기술인데 이것은 주로 managed code에서 C-style의 native APIs (C 함수들)를 불러다 쓰기 위한 용도다. 

둘째는 COM interop인데 이것은 native COM 인터페이스를 managed code로 부터 사용하거나 혹은 native COM 인터페이스를 managed APIs(함수들)로 부터 Export 하기 위해서 쓴다. 마지막으로 대망의 C++/CLI가 있는데 (과거에는 managed C++로 명명되었죠) 이것은 manged code와 native C++ code가 공존하는 형태로써 managed와 native 코드 간의 '다리'역활을 위한 용도로 디자인 되었다.


시간만 많으면 세가지 용도 모두에 대해서 쓰고 싶지만 일단 중요한게 C++/CLI이니까 그것만 자세히 살펴보겠다.


3. Interop Technologies: C++/CLI


C++/CLI is designed to be a bridge between the native and managed world, and it allows you to compile both managed and native C++ into the same assembly (even the same class) and make standard C++ calls between the two portions of the assembly. When you use C++/CLI, you choose which portion of the assembly you want to be managed and which you want to be native. The resulting assembly is a mix of MSIL (Microsoft intermediate language, found in all managed assemblies) and native assembly code. C++/CLI is a very powerful interop technology that gives you almost complete control over the interop boundary. The downside is that it forces you to take almost complete control over the boundary.
C++/CLI can be a good bridge if static-type checking is needed, if strict performance is a requirement, and if you need more predictable finalization. If P/Invoke or COM interop meets your needs, they are generally simpler to use, especially if your developers are not familiar with C++.
There are a few things to keep in mind when considering C++/CLI. The first thing to remember is that if you are planning to use C++/CLI to provide a faster version of COM interop, COM interop is slower than C++/CLI because it does a lot of work on your behalf. If you only loosely use COM in your application and don't require full fidelity COM interop, then this is a good trade-off.
If, however, you use a large portion of the COM spec, you'll likely find that once you add back the pieces of COM semantics you need into your C++/CLI solution, you'll have done a lot of work and will have performance no better than what is provided with COM interop. Several Microsoft teams have gone down this road only to realize this and move back to COM interop.
The second major consideration for using C++/CLI is to remember that this is only intended to be a bridge between the managed and native worlds and not intended to be a technology you use to write the bulk of your application. It is certainly possible to do so, but you'll find that developer productivity is much lower than in a pure C++ or pure C#/Visual Basic environment and that your application runs much slower to boot. So when you use C++/CLI, compile only the files you need with the /clr switch, and use a combination of pure managed or pure native assemblies to build the core functionality of your application.

C++/CLI는 원래 native와 managed 세계를 이어주는 브릿지 (다리) 역활 용으로 디자인 되었다. 그리고 이것은 managed 와 native C++ code 둘 다 동시에 하나의 공통 어셈블리 (심지어는 같은 클래스로) 컴파일 될 수 있게 해주었고 standard C++ 호출을 어셈블리의 두 영역간에 할 수 있게 해주었다. C++/CLI를 사용할때 당신은 어셈블리의 어떤 부분이 managed인지 혹은 native인지 결정할 수 있다. 이로써 결과물로 나오는 어셈블리는 MSIL (Microsoft intermediate language)와 native assembly 코드의 짬뽕이 된다. (MSIL은 managed code를 위해 사용되는 .NET Framework의 기반 언어 기술이다.) C++/CLI는 매우 강력한 interop 기술로써 당신에 거의 완벽에 가까운 interop 경계 컨트롤을 제공한다. (내 맘대로 왔다리 갔다리 할수 있다는 말). 문제는 모든 컨트롤을 제공하므로 일일이 내가 알아서 다 컨트롤 해야 한다.... 젠장 장점이 단점이네?ㅋㅋ


C++/CLI는 만약 어느 정도의 퍼포먼스가 요구되고 보다 예측 가능한 결과가 필요할 때, 그리고 static-type 체킹이 필요한 경우 좋은 다리 역활을 한다. 만약 P/Invoke나 COM interop이 내가 요구하는 것을 충족한다면 C++/CLI보다는 P/Invoke나 COM이 더 사용하기 쉽다. 특히 C++을 잘 모른다면... 더더욱.


C++/CLI을 사용할 때 명심해야 할게 몇가지 있다. 첫째는 C++/CLI가 COM interop보다는 빠르다는 점이다. (왜 같은 의미의 문장을 두번 이어서 썼는지 모르겠지만 암튼 C++/CLI가 COM보다 빠르다는 이야기) 왜냐면 COM은 사용자를 대신해서 많은 업무를 수행하기 때문이다. 만약 COM을 아주 약하게 사용한다면 (쬐끔만), 그러면 COM 쓰는 것도 괜찮다.


하지만 만약 COM의 많은 부분을 가져다 쓰게 되면 C++/CLI interop은 사실상 무용지물이 된다. 속도를 위해서 C++/CLI를 선택했으나 COM이 전체적인 퍼포먼스를 낮추기 때문에 애시당초 걍 COM interop으로 가는게 더 좋다는 말이네. 


C++/CLI를 사용할때 두번째 주의할 것은 이 interop은 다리 역활로 만들어진 것이지 프로그램을 그렇게 작성하시오라고 만든 것이 아니라는 점이다. 뭐 이건 당연한 이야기다. C++로 다 짤수 있는 프로그램을 굳이 C++/CLI로 짜서 다른 managed code랑 썪어 버릴 필요가 없다는 말이다. 이 점이 사실 뼈아프게 들리는 이유는 C++로 작성된 거대한 프로그램에서 몇가지 추가하고 싶은 기능이 있는데 그것이 C#과 같은 managed code로 작성하는 것이 내 입장에서는 더 편하게 느껴질때가 종종 있다. 이때 좀 갈등을 하는데 사실 그냥 좀 불편하더라도 Windows API를 이용하는 것이 C#을 이용하는 것보다 나은것 같다.


C#의 문제점은 폼안에 존재하는 각각의 컨트롤이 폼이 소유하고 있는 스레드를 제외하고는 스레드에 안전하지 않다는 점이다. 즉, C#은 설계 당시부터 다른 언어 (특히 C++)와의 섞어 쓰기에 대해 큰 고려를 안했던 것 같다. 물론 돌아가는 방법을 제공하기는 하지만 좀 완벽하지 못하다.


오늘은 여기까지만 쓰고 다음에 나머지 부분에 대해서 마무리하도록 해야겠다.

posted by 대갈장군