C#에서 C++ DLL 디버깅

 

C#에서 호출되는 DLL은 일반적으로 호출하기 전에 내보낸 함수를
extern "C" __declspec(dllexport)
BOOL Integrate3 (){...}과 같은 적절한 형식으로 표시하기만 하면 됩니다. 이러한 함수는 C#에서 다음과 같이 선언됩니다.

[DllImport("xxx.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
        public static extern bool Integrate3();, 여기서 호출은 비교적 간단하며 일부 데이터 유형은 MarshalAs 유형 변환을 통해 관리해야 합니다. 와 같은:

extern "C" __declspec(dllexport)
BOOL 통합(LPCWSTR 파일1, LPCWSTR 파일2, LPCWSTR 출력파일){...}

데이터 유형이 일치하지 않으므로 선언 시 유형 변환에 주의해야 합니다.

[DllImport("xxx.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
        public static extern bool Integrate([In, MarshalAs(UnmanagedType.LPWStr)]string file1,
            [In, MarshalAs(UnmanagedType.LPWStr) ]string file2, [In, MarshalAs(UnmanagedType.LPWStr)]string outputFile);

이런 방식으로 호출하는 데는 기본적으로 문제가 없으며, 초점은 데이터 유형 변환에 있습니다. 몇 번 시도해 보면 문제가 되지 않을 것입니다.

또 다른 소소한 실전 경험은 C#에서 C++ DLL을 디버깅하는 것입니다. 알면 몇 마디면 되는데, 모르면 시간이 많이 걸립니다. C# 프로젝트 속성의 "디버깅 항목 활성화"에서 , 한 항목: "관리되지 않는 코드 디버깅 활성화", 이것을 연결하면 일반 프로그램을 디버깅할 때와 마찬가지로 모든 것이 잘 될 것입니다.

C#이 C++ DLL을 호출하면 매개변수 전달이 문제가 됩니다. 오늘 제가 겪은 문제는 C++로 내보낸 함수의 매개변수가 문자열 유형이라는 점인데, C#에서 문자열 매개변수를 통해 호출하면 메모리가 손상되었거나 읽을 수 없다는 예외 메시지가 나타납니다. 나중에 C++ 내보내기 함수의 매개변수를 string에서 LPTSTR 유형, 즉 char* 유형으로 변경한 다음 C#에서 해당 매개변수를 StringBuilder 유형으로 변경했는데, 이는 매개변수 전달 문제를 해결했을 뿐만 아니라 매개변수 전달 문제 질문입니다.

DllImport 지식 확장: DllImport 
 .net 프레임워크 프로그램은 정적 DLL 진입점을 통해 네이티브 코드 라이브러리에 액세스할 수 있습니다. DllImport 특성은 외부 메서드 구현이 포함된 dll의 위치를 ​​지정하는 데 사용됩니다.

DllImport  특성  은  다음
  
  같이   정의   됩니다
.   public string EntryPoint ;   public bool ExactSpelling;   public bool PreserveSig;   public bool SetLastError;   public string Value { get {...} } } }  참고 :   1.  DllImport는 메서드 선언에만 배치할 수 있습니다.     2. DllImport에는 단일 위치 지정 매개변수가 있습니다. 가져온 메소드의 dll 이름이 포함된 dllName 매개변수를 지정하십시오.     3. DllImport에는 5개의 명명된 매개변수가 있습니다.













  

  



     a.CallingConvention 매개변수는 진입점의 호출 규칙을 나타냅니다. CallingConvention을 지정하지 않으면 기본값인 CallingConvention.Winapi가 사용됩니다.
     b. CharSet 매개변수는 진입점에 사용되는 문자 집합을 나타냅니다. CharSet을 지정하지 않으면 기본값 CharSet.Auto가 사용됩니다.
   c. EntryPoint 매개변수는 dll의 진입점 이름을 제공합니다. EntryPoint를 지정하지 않으면 메서드 자체의 이름이 사용됩니다.
   d.ExactSpelling 매개변수는 EntryPoint가 표시된 진입점의 철자와 정확히 일치해야 하는지 여부를 나타냅니다. ExactSpelling을 지정하지 않으면 기본값인 false가 사용됩니다.
   e. PreserveSig 매개변수는 메소드의 서명을 보존해야 하는지 변환해야 하는지 여부를 나타냅니다. 서명이 변환되면 HRESULT 반환 값과 해당 반환 값에 대한 retval이라는 추가 출력 매개 변수가 있는 서명으로 변환됩니다. PreserveSig를 지정하지 않으면 기본값인 true가 사용됩니다.
      f. SetLastError 매개변수는 메서드가 Win32 "마지막 오류"를 유지하는지 여부를 나타냅니다. SetLastError를 지정하지 않으면 기본값인 false가 사용됩니다. 
 4. 일회성 속성 클래스입니다.
 5. 또한 DllImport 특성으로 수정된 메서드에는 extern 수정자가 있어야 합니다.

다음은 C#에서 Win32 MessageBox 함수를 호출하는 예입니다:
  
using System,
using System.Runtime.InteropServices,
class MainApp
{

     //DllImport를 통해 user32.dll 클래스를 참조합니다. MessageBox는 user32.dll 클래스
 [DllImport("user32.dll", EntryPoint="MessageBox")] 에서 유래합니다
 . public static extern int MessageBox(int ​​​​hWnd, String strMessage, String strCaption, uint uiType);
 public static void Main()
 {
  MessageBox (0, "Hello, this is PInvoke!", ".net", 0 ); }
 }
거의
모든 객체 지향 프로그래밍 언어는 추상 클래스 개념을 사용합니다. 추상 클래스는 추상적인 것을 구현하는 데 더 큰 유연성을 제공합니다. 섹스. C#도 예외는 아니며 C#은 가상 인터페이스를 다루는 기술을 통해 추상 클래스의 적용을 심화시킵니다. 이에 대해 자세히 알아보려면 다음 섹션인 가상 인터페이스 재정의를 참조하세요.

여기에서 논의하는 것은 C#이 표준 동적 라이브러리를 호출하는 문제입니다. 이전 문서에서 언급한 것처럼 C#은 Win32API를 호출합니다. 원리는 동일합니다. 여기에서는 C에서 표준 동적 라이브러리를 작성하는 방법을 자세히 설명한 다음 C#이라고 부르세요.(이 글은 초보자에게 적합하고, 중간에 중복된 코드가 없으며, 간결하고 명확합니다.)
소프트웨어 환경: VC6.0 (물론 VC5의 다른 버전도 사용 가능)
1. 표준 동적 만들기 도서관


__declspec(dllexport) int __cdecl add(int, int);//이 문장은 동적 라이브러리가 외부에서 호출할 수 있는 함수 프로토타입을 출력함을 선언합니다.
int add(int a, int b) {//이 함수 구현
return a+ b ;
}


위의 간단한 3줄의 코드는 add 메소드를 선언하고, 입력 매개변수는 두 개의 int 매개변수이고 두 숫자의 합을 반환합니다.MyLib.c로 저장하고 컴파일 명령을 실행합니다.H:/XSchool/C#
-School
/ HowTo>cl /LD MyLib.c 80x86용
Microsoft (R) 32비트 C/C++ 최적화 컴파일러 버전 12.00.8168
Copyright (C) Microsoft Corp 1984-1998. 모든 권리 보유.

MyLib.c
Microsoft (R) 증분 링커 버전 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. 판권 소유.

/out:MyLib.dll
/dll
/implib:MyLib.lib
MyLib.obj
   MyLib.lib 라이브러리 및 MyLib.exp 객체 생성

컴파일이 동적 라이브러리를 성공적으로 생성했음을 나타내는 위의 출력이 있는지 확인하십시오.


2. System을 사용하고 System.Runtime.InteropServices를 사용하여 동적 라이브러리를 호출하는 C-Sharp 프로그램을 작성합니다
.//DllImport를 사용할 때 도입할 패키지입니다.

public class InvokeDll { [DllImport("MyLib.dll", CharSet=CharSet.Auto)] static extern int add(int a, int b);//Win32API와 동일한 외부 표준 동적 라이브러리를 선언합니다.

public static void Main() { Console.WriteLine(add(10,30)); } } InvokeDll.cs 파일로 저장하고 MyLib.dll과 동일한 디렉터리에 배치한 후 파일을 컴파일합니다. H:/XSchool/ C#-School/HowTo>csc Invokedll.cs는 실행 가능한 Invokedll.exe를 생성합니다.





추천

출처blog.csdn.net/dj1232090/article/details/3985215