C#

C# bool 형식 마샬링 할 때 주의 할 점 | C# Boolean Marshaling

DragonTory 2023. 2. 16. 15:41
반응형

C# bool 형식 마샬링 할 때 주의 할 점 | C# Boolean Marshaling

 

예로 아래와 같은 C++코드에서

// C++ Code 
#pragma pack(1)
class Data
{
public:    	
   	bool IsUsed;
	char Description[64];
}
#pragma pack()

C#으로 마샬링 하면

// C# Code
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public class Data
{
	public bool IsUsed;

	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
	public string Description;	
}

위와 같이 변경 할 수가 있는데 

이상하게 c++코드에서

sprintf(Description, "Test_Data");

으로 Test_Data 라는 문구를 넣는다고 하면 

C#  에서 출력은 "Test_Data"이 아니라 "t_Data" 처럼 짤려서 출력 되게 됩니다.

혹은 C#에서 illegal byte sequence 에러가 발생 하곤 합니다.

 

원인:

bool 타입이 C++과 C#에서 데이터 사이즈가 달라서 문제가 발생 합니다.

C++ bool type size : 1byte

C# bool type size : 4byte ( int type )

입니다. 따라서 c#에서  문자열에서 3바이트 만큼을 차지 하게 됩니다.

 

해결 1:

C#에서 타입을  UnmanagedType.U1으로 마샬링 하면 됩니다.

UnmanagedType.U1 : 1byte 데이터 타입

// C# Code
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public class Data
{
	[MarshalAs(UnmanagedType.U1)]
	public bool IsUsed;

	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
	public string Description;	
}

 

위와 같이 해당 bool 변수에

[MarshalAs(UnmanagedType.U1)]

을 적용 시켜 주면 문제가 해결 됩니다. 

 

해결 2:

C# 쪽에서 bool 형을 byte 형으로 변경 하면 됩니다. 

이 방법은 if(bool) 같은 식에서 좀 불편 합니다.

if(byte) 하면 컴파일 에러 발생.

byte a = true : false

이런 식에서도 에러 발생 해서 

if( byte != 0 ) 이나 bool = (byte != 0 ); 같은 추가적인 코드를 사용 해야 하는 불편이 따릅니다.

 

반응형