2010-06-02 4 views
5

이 질문은 이전 질문과 다를 수도 있습니다. 일련의 게시물을 읽었지 만 제 상황에 대해서는 명확하지 않습니다.C에서 C++ 라이브러리 호출 #

나는 momentics IDE를 사용하여 만든 C++ 라이브러리가 있습니다. 이 라이브러리를 C# 프로젝트에 사용할 수 있어야합니다.

누군가 나에게 넘겨지기 전에이 프로젝트를 진행하고있었습니다. 현재이 작업을 가능하게하기 위해 2 개의 레이어가 있습니다. 첫째, C++ 프로젝트에는 C++ 래퍼가있는 전체 라이브러리가 포함되어 있습니다. 이 프로젝트는 출력으로 dll을 생성합니다. 이 C++ dll은 C++ 프로젝트에 보내지며, dllimport는 C++ dll을 호출합니다. 이 C# 프로젝트는 DLL을 다시 만듭니다. 마지막으로, C# 응용 프로그램에서 라이브러리를 사용하려면이 두 dll에 대한 참조를 포함해야합니다.

올바른 방법일까요? 아마 프로세스를 단순화하는 방법이 있어야한다고 생각했습니다.

누군가이 질문에 나를 도울 수 있습니까?

+0

가능한 복제본 [C#에서 네이티브 C++를 호출하려면 어떻게해야합니까?] (http://stackoverflow.com/questions/2211867/how-do-i-call-native-c-from-c) – Randolpho

답변

7

, 나는 오히려 클래스와 같은 C++ 의미를 활용 있으리라 믿고있어 절차를 드러내는 것보다 이 경우 일반적으로 수동으로 생성 된 관리되는 C++ interop 라이브러리를 통해 수행됩니다.

기본적으로 Visual Studio에서 관리되는 C++ 라이브러리를 만들고 기존 C++ 라이브러리를 참조하며 기존 C++ 클래스를 관리하는 래퍼를 만듭니다. 그런 다음 C# 프로젝트에서이 (관리되는) C++ 어셈블리를 참조하고 C# 어셈블리에 원래 (관리되지 않는) C++ 라이브러리를 빌드 디렉터리에 배치되는 파일로 포함시킵니다.

P/Invoke (DllImport) 호출을 통해 C++ 클래스와 같은 항목을 참조 할 방법이 없기 때문에 필요합니다.

기본 라이브러리 인 경우 일련의 기능 만 수행하면 P/Invoke 기능을 통해 C# 프로젝트에서 직접 참조 할 수 있습니다.

위에서 언급 한 모든 라이브러리 (첫 번째 라이브러리의 경우 관리되지 않는 C++ 라이브러리, 관리되는 C++ 어셈블리 및 C# 프로젝트, 두 번째 경우에는 관리되지 않는 C++ 라이브러리 및 C# 프로젝트)가 있어야합니다. 그것들을 참조하는 모든 프로젝트에 포함됩니다. 관리되지 않는 라이브러리를 관리되는 어셈블리에 정적으로 연결할 수 없습니다.

+2

+1,하지만 당신이 .NET을 사용하지 않는 한 그것을 지적하고 싶습니다. 1.1에서 "managed C++"은 이제 "C++/CLI"라고 불리우며이 둘 사이에 큰 차이가 있습니다. – Randolpho

+0

또한, "관리되지 않는 라이브러리를 동적으로 연결할 수 없다"는 것을 의미한다고 생각합니다. * 정적으로 * 연결은 라이브러리를 사용하는 유일한 방법입니다. – Randolpho

+0

고맙습니다 .... 언급 한대로 관리되지 않는 라이브러리에는 클래스와 인터페이스가 있습니다. 이 경우, 나는 내 C# 응용 프로그램에서 관리되지 않는 C++ lib를 사용할 수 있도록 C++ 래퍼와 C# 래퍼가 있어야한다고 생각합니다. 이제 C++ 래퍼는 클래스의 인스턴스를 만들고 인터페이스를 구현하는 작업을 수행합니다. 다른 질문이 있습니다. extern "C"및 _dllexport 기능을 제공하는 관리되지 않는 lib 작업입니까? 현재는 그렇지 않지만 다음 프로젝트의 요구 사항으로 넣을 수 있으므로 꼭 확인하고 싶습니다. – Batul

0

당신 사용 : 당신이 C++ 라이브러리를 사용하고있는 점을 감안

DllImport

class Example 
{ 
    // Use DllImport to import the Win32 MessageBox function. 
    [DllImport("user32.dll", CharSet = CharSet.Unicode)] 
    public static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type); 

    static void Main() 
    { 
     // Call the MessageBox function using platform invoke. 
     MessageBox(new IntPtr(0), "Hello World!", "Hello Dialog", 0); 
    } 
} 
2

하나의 래퍼가 너무 많지만 어쩌면 누군가가 일종의 외관을 구현하거나 속성이나 다른 것을 추가하는 것처럼 보입니다. 관리되는 것과 관리되지 않는 것 간의 기본 연결은 멤버 함수가 아닌 "플랫"함수 호출의 DllImport이거나 멤버 함수를 호출하는 C++/CLI 코드입니다. 래퍼가 C++/CLI 인 경우 쓰기가 쉽고 (C++ 라이브러리의 헤더 만 포함) 가장 손쉽게 호출 할 수 있습니다 (C# 코드는 .NET 참조를 추가하고 정상적으로 수행함). 따라서 첫 번째 선택 항목이됩니다. 프로젝트에 C++ 전문 지식이 있습니다.

힘든 방식으로 수행하는 사람에게서 당신을 인계받은 사람처럼 들립니다. 방법이 20 개 미만인 경우 다시 시작하는 것이 좋습니다.

+0

처음부터 다시 시작하는 것이 나에게도 최고의 솔루션처럼 보였습니다.하지만 시작한 후에는 내가봤을 때 현재 솔루션이 올바른 방법임을 지적했습니다. 내가 제안한 바는 C++ 래퍼를 사용하여 관리되지 않는 C++ 라이브러리의 클래스를 처리 한 다음 C#에서 dllImport 호출을 사용하는 것입니다. 나 맞아? – Batul

+0

C++/CLI 래퍼를 추가하면 P/Invoke (DllImport)에서 사용자를 절약 할 수 있습니다. 기본적으로 C++/CLI 코드는 기본 코드를 사용하기 위해 기본적으로 "lib에 대한 헤더를 포함"할 수 있습니다. C++/CLI 코드에서'public ref class Foo'라는 것이 있다면 interop 메커니즘없이 C#에서 호출 할 수 있습니다. 그냥 참조를 추가하고 사용하면됩니다. –

+0

감사합니다. 케이트. 지금까지 읽은 것부터 DllImport는 관리되지 않는 lib에 플랫 구조가 필요합니다 (즉, 클래스 및 인터페이스 없음). 하지만 관리되지 않는 lib에는 클래스와 인터페이스가 있으므로 DllImport를 사용할 수 없다는 의미입니까? 그렇다면 C++/cli 래퍼를 만드는 것이 유일한 방법입니다. – Batul

관련 문제