ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Dotnet 환경에서 unmanaged 코드에 접근하는 방법
    2011. 1. 26. comments
    반응형
    1. COM Interop
     Dotnet CLR이 COM Interop을 위해 최적화된 마샬러(marshaler)를 제공

     ※ 먀샬링 : 
       클라이언트가 요청한 데이터를 서버가 인터페이스에 맞도록 데이터를 조직화 하고 변환하는 것.
       
       ex) 스택
       동일 어플리케이션에서 객체의 메서드를 호출할 떄 매개변수나 결과값은 스택을 통해 전달하는데,
       동일한  어플리케이션이 아닐 경우 서로 다른 스택을 사용하기 때문에 전달할수 없다. 
       이러한 경우에 메서드를 호출하기 위해 매개변수와 결과값은 바이트 스트림(메모리버퍼)에 기록하고 전달하는 방법으로 해결할 수 있는데
       바이트 스트림으로 변환하는 과정을 마샬링이라 한다.
       


    2. PInvoke(Platform Invoke)
     DLL이 외부에 노출하는 export 함수를 직접 호출하는 방법
     
       ※ Marshaling PInvoke : http://msdn.microsoft.com/en-us/library/fzhhdwae.aspx

    ex) win32 dll Import code

       [DllImport("kernel32.dll")]
        private static extern uint GetCurrentProcessId();
    
    
        public Form1()
        {
          InitializeComponent();
    
    
          string msg = String.Format("Current Process ID : {0}", GetCurrentProcessId());
          MessageBox.Show(this, msg, "", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
    


      2-1. 문자열
        Dotnet환경에서는 GC에 의해서 힙에 할당된 메모리가 해제될 때, 최적화를 위해 힙에 해제되지 않은 메모리를 컴팩하기 때문에 객체의 위치가 변경될 수 있음.
       C#에서 GC에게 메모리의 위치를 고정시킬 것이라는 명시(fixed)를 함으로써 해결한다.
       fixed 키워드를 사용하려면 프로젝트의 속성의 '빌드' 설정에서 안전하지 않은 코드 허용을 설정해주어야 한다.

        ex1)
      C++ 함수
    namespace export1 {
    
    
    public ref class Class1
    {
      public :
    
    
      static void UnmanagedFunc(unsigned char* str)
      {
        std::cout << "string : " << str << std::endl;
        str[0] = 'V';
      }
       // TODO: 여기에 이 클래스에 대한 메서드를 추가합니다.
    };
    
    }
    


        ex2) C#에서 C++ 모듈 함수 호출
         string inputData = "testStr";
          byte[] inputByteData = System.Text.Encoding.Default.GetBytes(inputData);
    
    
          unsafe
          {
            fixed (byte* aa = &inputByteData[0])
            {
              export1.Class1.UnmanagedFunc(aa);
            }
          }
          
          string output  =  System.Text.Encoding.Default.GetString(inputByteData);
    
      
          -> 결과값 : VestStr
     
    • 주의사항 : 매개변수를 전달하기 위해서는 데이터 타입을 일치시켜야 한다. 동일한 표현이 아닐수 있기 때문에 아래의 타입을 확인한다
              ※ Marshaling PInvoke Data Types : http://msdn.microsoft.com/en-us/library/ac7ay120.aspx

     


    반응형

    댓글

Designed by Tistory.