2010-03-28 5 views
23

C++과 C#을 결합하는 것이 좋은 생각입니까? 즉각적인 문제가 있습니까?C++과 C#의 결합

저는 C++이 될 수있는 일부 부품과 효율성을 높이기 위해 C#이되는 부품이 필요합니다. C#에서 기본 C++ DLL을 사용하여 달성하는 가장 좋은 방법은 무엇입니까?

답변

25

예 제품에 C# 및 C++을 사용하는 것은 매우 일반적이며 좋은 아이디어입니다.

경우에 따라 관리되는 C++을 사용할 수 있습니다.이 경우 다른 .NET 모듈과 마찬가지로 관리되는 C++ 모듈을 사용할 수 있습니다.

일반적으로 C#에서는 할 수있는 모든 작업을 수행합니다. C++에서 수행해야하는 부분에 대해 일반적으로 C++ DLL을 만든 다음 C#에서 해당 DLL을 호출합니다. 매개 변수의 마샬링은 자동으로 수행됩니다. 여기

는 C 번호로 DLL 내부에서 C 함수를 가져 오기의 예입니다

[DllImport("user32", CharSet=CharSet.Auto, SetLastError=true)] 
internal static extern int GetWindowText(IntPtr hWnd, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpString, int nMaxCount); 
+0

.NET 용 광고입니까? 크로스 플랫폼 호환성, 연결 문제, 학습 곡선 등은 어떻습니까? –

+1

학습 곡선? 언어를 결합하려고 할 때 C++과 C#의 기초를 알고 있다고 가정합니다. 크로스 플랫폼? C++에서 크로스 플랫폼 코드를 작성하는 것이 훨씬 어렵지만 가능합니다. C#과 결합 할 때 조금 더 쉬워 보입니다. 더 높은 수준의 코드는 특정 플랫폼에서로드 및 사용할 WHCH C/C++ 부분을 결정할 수 있습니다. – Harry

+0

@ 해리 : 나를 보여줄 때 답을 받아 들일 것입니다 (예 : C) # –

29

문제는 위해 사용하는 속성이 아니라 무엇을, 자신의 C#을 솔루션에 자신의 C++ 코드를 통합하는 방법을 명확하게 win32 API에서 기존 함수를 호출합니다. 답변이 이미 접수되었다고하더라도 불완전한 것으로 생각되며 다음 내용이 적용됩니다.

예, 작업 속도가 빨라지고 리소스를 적게 사용하며 경우에 따라 .net 프레임 워크에서 사용할 수없는 방법에 액세스하는 경우가 일반적입니다.

당신의 목표는 네이티브 관리되지 않는 C++ 라이브러리를 코딩 할 필요가 효율성을 얻을 경우, 당신은 Visual Studio 및 참조하여 C# 프로젝트에서이 라이브러리의 새로운 관리되지 않는 C++ 프로젝트를 (즉, DLL 라이브러리로 컴파일)이 생성됩니다 .

경우에 따라 관리되지 않는 C++ 라이브러리를 작성한 것으로 보이며 다음이 적용됩니다.

에 대해 묻는 즉각적인 문제는 배포 및 난독 화에 영향을 미칩니다.

  • 배포 : 명심 당신이 어떤 CPU에서 실행됩니다 빌드 C#을 DLL을, 32 및 64 비트,하지만 라이브러리 프로그램을 강제 ++이 새로운 네이티브 및 관리되지 않는 C가 될 중 하나 32 또는 64 특정.

    은 Visual Studio를 구성 관리자에서 구성 무언가 이며, , 당신은에있는이 될 것입니다, C# 어셈블리 및 새로운 관리되지 않는 C++ 라이브러리에 대한 anycpu를을 선택합니다 컴파일 시간에 알아서한다 자체 프로젝트이기 때문에 win32 또는 x64에서 선택할 수있는 을 갖게됩니다.

    그래서 지금이 설정을해야합니다, 당신 가 64 비트에 초점을 맞출 수 이 별도의 설정, 32 일 및 지원은 매우 빠르게 떨어지고 64 또는 32 비트 이후 또 다른 하나를 가지고 최선의 방법을 권장합니다 만.

    또한 라이브러리가 Visual Studio에서 제공하는 VC++ 재배포 가능 파일을 참조 할 수 있습니다.이 파일은 일부 버전이 여러 OS에 포함되어 있지만 컴파일 할 때 포함시켜야 할 수도 있습니다. 응용 프로그램과 함께 배포하는 것이 가장 좋습니다. 이 팩이 누락 된 경우 대상 시스템은 eventviewer-> 어플리케이션 로그에 SideBySide 예외를 갖습니다.

    관리되지 않는 코드에서 throw 된 예외를 catch하고 처리하려면 catch() 뒤에 괄호 안에 예외 유형이없는 빈 catch 만 catch합니다. 따라서 관리되지 않는 코드에 호출을 래핑하여 관리되지 않는 코드 내부에서 발생하는 모든 관리되지 않는 예외를 처리 할 수 ​​있습니다. catch (Exception)와 같은 .net 유형을 사용하면 예외가 발생합니다. 매니지 코드 내의 관리되지 않는 예외를 잡을 수있는 유일한 방법은이 형식입니다.

    • 
          try 
          { 
           //call unmanaged code 
          } 
          catch 
          { 
           //handle unmanaged exception 
          } 
      

    는 난독 : 지금 관리되지 않는 코드를 호출하는 C#을에서 수행 모든 메소드 호출은 자동으로 이름을 바꾸는에서 를 제외됩니다. 그리고 플립 측면에서, 가 관리되지 않는 C++ 라이브러리가 관리되는 어셈블리에서 메소드를 호출 할 을 필요로하는 경우, 사람들은 에게 그들을 호출하는 C++ 라이브러리에 볼 수 되기 위해, 수동으로 이름을 변경에서 제외해야합니다.

필요한 경우 Windows와 같은 잘 알려진 C++ 라이브러리를 호출하기 만하면 이전 답변에서 제안 된 [DllImport()] 특성 만 사용하여 관리되지 않는 새 C++ 프로젝트를 만들 필요가 없습니다. 그리고이 경우에 당신은 C++의 차이 대 C 번호에 대해이 기준에 http://www.pinvoke.net/

+0

*'관리되지 않는 코드에서 던져진 예외를 잡아서 처리하십시오. '* -이 것은 다시 말해야하며, 예외 타입 지정없이 catch하면 예외를 잡을 수 있다는 것을 의미합니다. 특정 처리를위한 쉬운 방법은 없지만 C# 응용 프로그램을 계속 실행하면 ... [.net - C# 코드에서 네이티브 예외를 catch 할 수 있습니까? - [Stack Overflow] (https://stackoverflow.com/questions/150544/can-you-catch-a-native-exception-in-c-sharp-code) 및 [CA2102 : 일반 핸들러에서 비 CLSComplant 예외 잡기] (https://msdn.microsoft.com/en-gb/bb264489.aspx) – Wolf

-2

추가 정보를 살펴보고이를 병합 문제를 possibles 수 :

  • C 번호는 자바와 같은 해석이다. C++는 네이티브 바이너리로 컴파일됩니다. 그 점은 다음과 같은 점에서 더 많은 차이점을 설명합니다.
  • 플랫폼 호환성 : C#, 해석 된대로 및 Microsoft 제품, Windows에서 제대로 작동합니다. 덕분에 좋은 프로젝트 덕분에 Mono이되었지만 다른 플랫폼에서는 그렇지 않습니다 (Android, IOS 등). .) 운영 체제를 지원하지 않는 곳에서 임베디드 용 소프트웨어를 작성하거나 OS 자체를 작성하려면 대부분 C#을 사용할 수 없습니다. 컴파일러를 사용하자마자 C++은 완전히 크로스 플랫폼입니다 (일반적으로 그렇습니다).
  • 해석 된 코드는 일반적으로 이진 코드 [1]보다 한 단계 진도가 낮습니다. 그래서 C++ 링크를 사용할 것입니다.
  • 중간 코드 : 중간 코드는 특정 아키텍처에서 사용 가능한 모든 인터프리터에서 작동하며 C++에서는 각 아키텍처에 대해 다시 컴파일해야합니다.
  • 학습 곡선 : 개발자는 학습 언어를 배워야 학습 시간이 늘어납니다. 또한 두 언어로 전문가를 찾는 것이 더 어렵습니다.
  • IDE : C++의 경우 텍스트 편집기 만 있으면 충분합니다. C#의 경우 대부분 특정 IDE가 필요합니다.
  • 실시간 : C#으로 실시간 조건을 상상하기가 어려워 보입니다.
  • 일부 품질 보증은 C# 코드 (중요한 소프트웨어)로는 불가능할 수 있습니다.

그들을 결합하는 것이 좋은가요?

아마도 프로젝트에 따라 다릅니다. Windows에서의 대형 HMI 개발의 경우 개발 시간이 단축 될 수 있습니다. 그러나 다른 소프트웨어 요구 사항으로 인해 C++로만 제한 될 수 있습니다.


[1]이 코드가 더 빨리 바이너리 코드보다 어떤 경우에 해석 여러 번 읽고,이 오해로 인해

: 통역사는 당신이 전화를 그렇게 할 때, 편의를 위해 몇 가지 기능을 구현 (예) sort(), 실제로는이 함수의 이진 구현을 호출합니다. 이 함수가 잘 최적화되면 최종 시간은 더 빠를 수 있지만 모든 요소가 바이너리로 실행되고 해석 된 구성 요소가 정렬하는 데 필요한 모든 시간보다 최소화되기 때문에. 반면, 두 언어 모두에서 완전한 로직을 코딩하면 바이너리 버전이 훨씬 더 빠릅니다. 이유는 간단합니다. 인터프리터는 코드 외에도 모든 언어 프레임 워크를 실행하는 바이너리입니다.

+1

Jit은 해석 된 것과 다릅니다. Jit은 기계 코드로 컴파일 할 수 있습니다. – tohava

+0

일반적인 경우가 아닌 "완전히 컴파일 된"C#을 사용하더라도 대부분의 확인은 여전히 ​​유효합니다. 단지 그것은 해석되지 않으며 성능 차이는 그다지 크지 않습니다. –