`return: MarshalAs(UnmanagedType.I1)`

위린이·2025년 9월 11일

1. 기본 개념

  • P/Invoke로 C/C++ DLL 함수를 불러올 때, C#은 자동으로 타입을 변환(마샬링)해 줍니다.
  • 하지만 C/C++ 쪽의 타입과 .NET 쪽 타입이 일치하지 않는 경우, 어떤 방식으로 변환해야 할지 명확히 알려줘야 할 때가 있습니다.
  • 그때 쓰는 게 바로 [MarshalAs(UnmanagedType.…)] 특성(attribute)입니다.

2. UnmanagedType.I1 의 의미

  • I1 = signed 1-byte integer
  • 즉, C/C++의 char (보통 1바이트 정수형)과 매핑됩니다.
  • 흔히 DLL에서 bool 같은 값을 char 또는 int8_t로 반환하는 경우, 이를 C#에서 정확히 받으려면 지정해 줘야 합니다.

예를 들어 DLL 함수가 이렇게 생겼다고 해봅시다:

extern "C" __declspec(dllexport) char MyFunc();

이 함수는 1바이트 값을 리턴합니다. 그런데 C#에서는 기본 bool4바이트(Int32) 로 마샬링되는 게 기본이어서, 그냥 bool을 쓰면 값이 꼬일 수 있습니다.

이때:

[return: MarshalAs(UnmanagedType.I1)]
[DllImport("MyDll.dll")]
public static extern bool MyFunc();

이렇게 쓰면 C#에서 MyFunc()의 반환값을 1바이트짜리 bool로 정확하게 해석합니다.


3. 안 붙였을 때 문제

  • MarshalAs를 지정하지 않으면 C#은 bool ↔ C/C++ 타입을 4바이트 기준(BOOL 타입)으로 변환합니다.

  • 결과적으로:

    • C++에서 char1을 반환해도, C#에서 잘못 해석해 false로 나올 수 있음.
    • 혹은 스택 정렬 문제로 예기치 않은 버그가 발생.

4. 정리

  • return: MarshalAs(UnmanagedType.I1)
    → "이 함수의 반환값은 unmanaged world에서는 **1바이트 정수(char)**이고, 이를 C#에서 bool로 마샬링해라"라는 의미.
  • DLL에서 반환하는 값이 BOOL(4바이트)인지 char/bool(1바이트)인지 확실히 구분해야 올바르게 써야 합니다.

0개의 댓글