본문 바로가기
프로그래밍/C#

P/Invoke란 무엇인가?

by bantomak 2023. 5. 19.

P/Invoke란?

C# / ,NET에서 Native DLL (Unmanaged DLL)에 있는 함수를 호출하는 것을 Plaform Invoke 혹은 줄여서 P/Invoke라고 부른다. 예를 들어, C#에서 윈도우즈 운영체제의 Win32 API를 호출한다던가, C/C++로 작성된 Native DLL의 함수를 호출할 필요가 있을때, P/Invoke 방식을 사용한다.

 

P/Invoke를 사용하기 위해서는

  1. System.Runtime.InteropServices 네임스페이스에 있는 DllImport를 사용하여 어떤 DLL에서 함수를 가져올지를 지정한다.
  2. 해당 함수의 원형을 C# 메서드 원형으로 정의해 준다.
  3. 이때 C# 메서드는 static extern으로 지정한다.

예제 코드

using System;
using System.Runtime.InteropServices; // for DllImport

namespace PInvokeTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Beep(100, 1000);
            Beep(200, 1000);
            Beep(300, 1000);
            Console.ReadKey();
        }

        [DllImport("Kernel32.dll")]
        public static extern bool Beep(uint frequency, uint duration);
    }
}

 

C#에서 C/C++ 함수를 호출하는 방법

C#에서 Win32 API를 호출하는 방법과 비슷하게, 자신이 만든(혹은 3rd Party) C/C++ Native DLL안의 함수를 호출할 수 있다.

 

  1. C/C++ 코드에서 extern C 블록을 작성해서 외부에서 사용이 가능하도록 선언해야한다.
  2. 다음 C# 프로젝트에서 C/C++ DLL을 복사한 후, DllImport를 정의하여 사용한다.
    (통상적으로 C/C++ DLL은 C# 실행파일과 같은 폴더에 두어야 한다.)
// C++ 코드 (MyLib.dll)

#include "stdafx.h"

extern "C" {
    __declspec(dllexport) float WINAPI ConvertFahrenheitToCelsius(float f);    
}

float WINAPI ConvertFahrenheitToCelsius(float f)
{
    float c = (f - 32) * 5.0 / 9.0;
    return c;
}

// C# 코드 
using System;
using System.Runtime.InteropServices;

namespace UsePInvoke
{
    class Program
    {
        static void Main(string[] args)
        {
            float f = 82.50F;
            float c = ConvertFahrenheitToCelsius(f);

            Console.WriteLine("{0} C", c);
        }

        [DllImport("MyLib.dll")]
        public static extern float ConvertFahrenheitToCelsius(float f);
    }
}

 

보통 해당 기능은 외부의 3rd Party DLL을 가져다 쓸때 사용한다. 최근에 배틀아이를 연동하면서 해당 기능의 존재에 대해서 처음으로 알았다. 그 당시 전혀 모르는 상태여서 당황했던 기억이 있다. 까먹지 않도록 정리해서 리마인드 하도록 하자.

댓글