이번 절의 fixed는 이전 절의 예약어와 이름은 같지만 그 용도는 다르다. 이 구문을 이해하기

위해서는 C/C++ 지식이 요구된다. 가령 다음과 같은 C++ 구조체가 있을때,

// C/C++로 정의한 구조체
struct CppStructType
{
public :
		int fields[2];
		__int64 dummy[3];
};
		

이것을 인자로 받아들이는 C++ DLL 함수가 있다고 가정해 보자.

// C/C++로 정의한 함수
__declspec(dllexport) void __stdcall ProcessItem(CppStructType *value)
{
		for (int i = 0; i < 2; i++)
		{
				value->fields[i] = (i + 1) * 2;
		}

		for (int i = 0; i < 3; i++)
		{
				value->dummy[i] = (i + 1) * 20;
		}
}

위의 C++ 함수를 extern 예약어를 통해 C#에서 호출하려면 우선 CppStructType에 맞는 구조체를

정의해야 한다. 그런데 이 구조체를 다음과 같이 정의할 수 있을까?

// C#의 struct
struct CSharpStructType
{
		public int[] fields;
		public long[] dummy;
}

static void Main(string[] args)
{
		CSharpStructType item = new CSharpStructType();
		item.fields = new int[2];
		item.dummy = new long[3];
}

CppStructType과 CSharpStructType이 어떻게 메모리에 할당되는지 살펴보면 그 답을 알 수 있다.

CppStructType의 메모리 할당이 연속적인 반면, C#의 경우 필드마다 배열이 다시 참조 객체이므로

별도의 메모리를 할당받고 CSharpStructType의 필드는 그에 대한 참조 주소를 갖는 형식으로

할당된다. 따라서 C++의 ProcessItem 함수를 다음과 같이 호출하면,

struct CSharpStructType
{
		public int[] fields;
		public long[] dummy;
}

class Program
{
		[DllImport("...C/C++ processItem 구현.dll...")]
		internal static unsafe extern int ProcessItem(CSharpStructType value);

		unsafe static void Main(string[] args)
		{
				CSharpStructType item = new CSharpStructType();
				item.fields = new int[10];
				item.dummy = new long[20];

				ProcessItem(item); // 프로세스 비정상 종료
		}
}

C++ DLL 측에서 참조 오류 예외가 발생하면서 프로그램이 비정상 종료되게 된다. 이런 문제를 해결