Unity LZ4
๐ก ARMv7 + IL2CPP ํ๊ฒฝ์์ LZ4 ํฌ๋์ ๋ฌธ์ ์ ํด๊ฒฐ์ฑ
Unity์์ IL2CPP + ARMv7 ํ๊ฒฝ์์ **LZ4 ์์ถ์ ์ฌ์ฉํ ๋ ๋ฐ์ํ๋ ์ ๋ ฌ ๋ฌธ์ (unaligned access)**๋ก ์ธํด ํฌ๋์๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ์๋ค๋ฉด, ๋ค์ดํฐ๋ธ LZ4 ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ง์ ์ํฌํธํด์ ์ฌ์ฉํ๋ ๋ฐฉ์์ ์ข์ ํด๊ฒฐ์ฑ ์ด ๋ ์ ์์ด.
๐น ๋ฌธ์ ์ ์์ธ (Unaligned Access ๋ฌธ์ )
- ARMv7 ์ํคํ ์ฒ๋ ๋ฉ๋ชจ๋ฆฌ ์ ๋ ฌ(Alignment)์ ์๊ฒฉํ๊ฒ ์๊ตฌํจ.
- IL2CPP๋ C# ์ฝ๋๋ฅผ ๋ณํํ๋ฉด์ C++ ์ฝ๋์์ ์ ๋ ฌ๋์ง ์์ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ์ ๊ทธ๋๋ก ์ํํ ์ ์์.
- Mono์์๋ ์๋์ผ๋ก ์ ๋ ฌ๋ ์ ๊ทผ์ ๋ณด์ฅํ์ง๋ง, IL2CPP์์๋ ๊ฐ๋ฐ์๊ฐ ์ ๋ ฌ์ ์ง์ ์ ๊ฒฝ ์จ์ผ ํจ.
- LZ4์ ๊ธฐ๋ณธ ๊ตฌํ์ ๋น ๋ฅธ ์ฒ๋ฆฌ๋ฅผ ์ํด unaligned access๋ฅผ ํ์ฉํ๋ ๋ฐฉ์์ผ๋ก ์ค๊ณ๋จ, ์ด ๋๋ฌธ์ ํฌ๋์๊ฐ ๋ฐ์ํ ์ ์์.
๐น ํด๊ฒฐ ๋ฐฉ๋ฒ: ๋ค์ดํฐ๋ธ LZ4 ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ธฐ
โ ๋ฐฉ๋ฒ 1: C++ ๊ธฐ๋ฐ์ LZ4 ๋ค์ดํฐ๋ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ
๐ก LZ4์ ๊ณต์ C ๊ตฌํ์ ๋น๋ํด์ Unity์์ P/Invoke๋ฅผ ํตํด ์ฌ์ฉํ๋ฉด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์.
- ARMv7 ํ๊ฒฝ์์๋ ์์ ํ ์ ๋ ฌ์ ๋ณด์ฅํ๋ ๋ค์ดํฐ๋ธ ์ฝ๋๋ก ์คํ๋จ.
- Unity์ IL2CPP์ ํธํ ๊ฐ๋ฅ.
- ๋ค์ดํฐ๋ธ ์ต์ ํ๋ฅผ ํ์ฉํ์ฌ ์ฑ๋ฅ์ด ๋ ์ข์ ์๋ ์์.
๐น 1. ๋ค์ดํฐ๋ธ LZ4 ๋น๋ (C++ ๋ผ์ด๋ธ๋ฌ๋ฆฌ)
- LZ4 ๊ณต์ ๋ฆฌํฌ์งํ ๋ฆฌ์์ ์ต์ C++ ์์ค๋ฅผ ๋ค์ด๋ก๋
- Android์ฉ .so ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋น๋
- jni/Android.mk ํ์ผ์ ์์ฑ ํ, LZ4 C ์ฝ๋ ํฌํจ
- ndk-build๋ฅผ ์ฌ์ฉํ์ฌ .so ํ์ผ ์์ฑ
- liblz4.so๋ฅผ Unity์ Plugins/Android/ ํด๋์ ๋ฐฐ์น
- iOS ๋ฐ Windows์ฉ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋น๋
- iOS: Xcode์์ liblz4.a(์ ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ) ๋๋ liblz4.dylib(๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ) ์์ฑ
- Windows: Visual Studio์์ lz4.dll ๋น๋
๐น 2. Unity์์ P/Invoke๋ก ๋ค์ดํฐ๋ธ LZ4 ํธ์ถ
Unity์์ DllImport๋ฅผ ์ฌ์ฉํ์ฌ ๋ค์ดํฐ๋ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํธ์ถํ๋ฉด ๋จ.
๐ธ C++ ๋ค์ดํฐ๋ธ ํจ์ (LZ4Wrapper.cpp)
#include "lz4.h"
extern "C" {
int LZ4_Compress(const char* src, char* dst, int srcSize, int maxDstSize) {
return LZ4_compress_default(src, dst, srcSize, maxDstSize);
}
int LZ4_Decompress(const char* src, char* dst, int compressedSize, int dstCapacity) {
return LZ4_decompress_safe(src, dst, compressedSize, dstCapacity);
}
}
๋น๋ ํ liblz4.so, liblz4.dylib, lz4.dll์ Unity์ Plugins ํด๋์ ์ถ๊ฐ.
๐น 3. C#์์ P/Invoke๋ก ํธ์ถ
using System;
using System.Runtime.InteropServices;
public static class LZ4Native
{
const string LIB_NAME =
#if UNITY_IOS
"__Internal";
#elif UNITY_ANDROID
"liblz4";
#elif UNITY_STANDALONE_WIN
"lz4";
#else
"lz4";
#endif
[DllImport(LIB_NAME, EntryPoint = "LZ4_Compress")]
public static extern int Compress(byte[] src, byte[] dst, int srcSize, int maxDstSize);
[DllImport(LIB_NAME, EntryPoint = "LZ4_Decompress")]
public static extern int Decompress(byte[] src, byte[] dst, int compressedSize, int dstCapacity);
}
์ด์ C#์์ LZ4Native.Compress ๋ฐ LZ4Native.Decompress๋ฅผ ํธ์ถํ๋ฉด ๋ค์ดํฐ๋ธ LZ4๋ฅผ ์ฌ์ฉํ ์ ์์.
๐น ๊ฒฐ๋ก : ๋ค์ดํฐ๋ธ LZ4 ์ฌ์ฉ์ด ์ข์ ํด๊ฒฐ์ฑ !
โ
IL2CPP์์ ๋ฐ์ํ๋ unaligned access ๋ฌธ์ ๋ฅผ ํผํ ์ ์์.
โ
ARMv7 ํ๊ฒฝ์์๋ ์์ ์ ์ผ๋ก ๋์ ๊ฐ๋ฅ.
โ
์ฑ๋ฅ ํฅ์ ๊ฐ๋ฅ (๋ค์ดํฐ๋ธ ์ฝ๋ ์คํ ์ต์ ํ).
โ
Unity์ ๋ค์ํ ํ๋ซํผ(Android, iOS, Windows)์์ ๋์ผํ ๋ฐฉ์์ผ๋ก ๋์ ๊ฐ๋ฅ.
๐ ๊ฒฐ๋ก ์ ์ผ๋ก, ๋ค์ดํฐ๋ธ LZ4 ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ํฌํธํด์ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ ํด๊ฒฐ ๋ฐฉ๋ฒ ์ค ํ๋์ผ! ๐