본문 바로가기

C#

C# Marshal 클래스 활용한 메모리 변환 기법

C#에서 메모리 변환은 비관리 코드와 상호작용할 때 필수적인 기술입니다. 이를 위해 Marshal 클래스를 사용하면 포인터, 구조체 등 복잡한 메모리를 안전하게 다룰 수 있습니다.

1. Marshal 클래스란?

Marshal 클래스는 System.Runtime.InteropServices 네임스페이스에 포함되어 있으며, 메모리 할당, 해제, 복사, 포인터 조작 등을 지원합니다. 주로 unmanaged 메모리와 데이터 구조를 다룰 때 사용합니다.

2. 주요 메서드와 사용법

가장 자주 사용하는 메서드는 다음과 같습니다.

  • AllocHGlobal: 비관리 메모리 할당
  • FreeHGlobal: 할당한 메모리 해제
  • StructureToPtr: 구조체를 포인터로 변환
  • PtrToStructure: 포인터를 구조체로 변환

3. 예제 코드

아래 예제는 구조체를 메모리에 복사하고 다시 읽는 기본적인 메모리 변환 기법입니다.

using System;
using System.Runtime.InteropServices;

struct Person
{
    public int Id;
    public float Score;
}

class Program
{
    static void Main()
    {
        Person p = new Person { Id = 123, Score = 98.6f };

        // 구조체 크기만큼 메모리 할당
        IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(p));

        try
        {
            // 구조체 데이터를 비관리 메모리로 복사
            Marshal.StructureToPtr(p, ptr, false);

            // 비관리 메모리를 다시 구조체로 읽기
            Person p2 = Marshal.PtrToStructure(ptr);

            Console.WriteLine($"Id: {p2.Id}, Score: {p2.Score}");
        }
        finally
        {
            // 메모리 해제
            Marshal.FreeHGlobal(ptr);
        }
    }
}

4. 주의사항

비관리 메모리는 수동으로 할당과 해제를 관리해야 하므로 반드시 해제를 잊지 말아야 합니다. 또한, 구조체에 참조 타입이 포함되어 있다면 StructureToPtr 메서드 사용 시 메모리를 신중히 다뤄야 합니다.

이처럼 Marshal 클래스를 활용하면 C#에서 메모리 관리를 직접 제어할 수 있어 성능과 안전성을 동시에 챙길 수 있습니다.