반응형
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 ); 같은 추가적인 코드를 사용 해야 하는 불편이 따릅니다.
반응형
'C#' 카테고리의 다른 글
C# bool 타입을 byte 타입으로 변환 | Convert bool to byte | Convert byte to bool (0) | 2023.02.17 |
---|---|
마샬링이란? | Marshaling? (0) | 2023.02.17 |
C# Marshaling Data Type (0) | 2023.02.15 |
ArgumentException: Partial byte sequence encountered in the input. (0) | 2023.02.13 |
C++ 클래스를 DLL로 C#에서 사용 하기 | Marshalling C++ class to C# (0) | 2023.01.30 |