본문 바로가기

게임서버(Game Server)

[게임서버] 유니티(C#)에서 Pragma pack 사용법

 

 

Pragma pack 이란

Pragma pack 이란 구조체의 바이트 패딩을 막는 것을 말한다.

 

바이트 패딩이란 32비트 CPU 기준으로 한 번에 32비트 즉 4바이트씩 메모리를 가져와서 연산할 수 있도록 컴파일러가

자료형의 크기를 최적화하는 것을 말한다. ( 무조건 4바이트는 아니다. 디폴트 패킹 값은 8바이트라고 한다.)

 

요약하면 char는 1의 배수, int는 4의 배수,  double은 8의 배수에 정렬되도록 올라간다고 한다.

 

관련 글

sleep365.tistory.com/81

 

C++에서 사용법

C++에서는 Pargma pack()이라는 전처리기 문을 사용하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<iostream>
 
#pragma pack(push, 1)
struct TestStruct {
    int        first;
    char    second;
    int        third;
};
#pragma pack(pop)
 
struct TestStruct2 {
    int        first;
    char    second;
    int        third;
};
 
int main() {
    TestStruct test;
    TestStruct2 test2;
 
    std::cout << "using Pragma pack " << sizeof(test) << "\n";
    std::cout << "not using Pragma pack " << sizeof(test2) << "\n";
 
}
 

 

결과

 

유니티(C#)에서 사용법

유니티 즉 C#언어에서는 이러한 전처리기 문을 사용할 수 없다. C#에서 이와 같이 사용하려면

StructLayoutAttribute 클래스를 사용하면 된다. 추가적으로 구조체의 크기를 측정할 때 에는 Marshal.Sizeof() 메서드를 사용하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
  [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct TestStruct
    {
        public int first;
        public char second;
        public int third;
    }
 
    public struct TestStruct2
    {
        public int first;
        public char second;
        public int third;
    }
 
 
 
public class MyUnity: MonoBehaviour{
 
    // Start is called before the first frame update
    void Start()
    {
        TestStruct test;
        first = 0;
        second = 'a';
        third = 15;
        int size=Marshal.SizeOf(test);
 
        Debug.Log("using Pragma pack: " + size);
 
        TestStruct2 test2;
        first = 0;
        second = 'a';
        third = 15;
        int size2 = Marshal.SizeOf(test2);
 
        Debug.Log("not using Pragma pack: " + size2);
    }
 
 
 
    // Update is called once per frame
    void Update()
    {
        
    }
}
 

 

Unity에서의 결과

후기

Unity를 시작 후 C++과 프로토콜을 맞추기 위해서 Pragma Pack()을 사용하려 했지만 Unity에서 사용을 할 수 없어서

겸사겸사 정리를 하였다. 아직 Unity와 C#이 익숙지 않아서 잘 붙일 수 있을지 모르겠다.

 

카테고리를 게임 서버로 한 이유는 내가 게임 서버랑 Unity를 붙이는 과정에서 글을 작성했기 때문이다. 

 

출처 및 레퍼런스

 

MSDN

StructLayoutAttribute: https://docs.microsoft.com/ko-kr/dotnet/api/system.runtime.interopservices.structlayoutattribute?view=netframework-4.8

 

Marshal.SizeOf 메서드: https://docs.microsoft.com/ko-kr/dotnet/api/system.runtime.interopservices.marshal.sizeof?view=netframework-4.8