간략한 팁입니다.
win32 API에 보면 bool type이 있습니다.
MFC에는 BOOL type이 있지요.
언듯보면 비슷해보이고 MFC에서 두타입을 혼용해도 사실 많은 경우에 별 문제가 발생하지 않습니다.
하지만 두 타입에는 큰 차이가 있습니다. 크기지요.
sizeof 함수를 이용해서 두 개의 크기를 찾아보면 이와같이 나타납니다.
bool : 1 byte
BOOL : 4 byte
BOOL 타입의 선언을 찾아가보시면 int형으로 선언이 되어있는걸 볼 수가 있습니다.
그래도 어짜피 BOOL 타입는 0과 1을 빼면 들어갈 것이 없기에 별 문제가 없습니다.
하지만 C#으로 Marshaling을 하게 되면 문제가 될 소지가 있습니다.
아래와 같은 경우지요.
MyDll.dll
//구조체
typedef struct _BOOL_ARRAY
{
BOOL bA;
BOOL bB;
BOOL bC;
BOOL bD;
}BOOL_ARRAY;
//선언
extern "C" __declspec(dllexport) void SetBOOLArray(BOOL_ARRAY stBoolArray);
이런식으로 선언된 C++ Dll이 있습니다. 이런 경우 c#으로 Marshaling을 하면 이렇게 되겠지요.
//구조체
public struct BOOL_ARRAY
{
public Boolean bA;
public Boolean bB;
public Boolean bC;
public Boolean bD;
};
//선언
[DllImport("MyDll.dll")]
public static extern void SetBOOLArray(BOOL_ARRAY stBoolArray);
****이렇게 하면 안됩니다!!!***
이유는 이렇습니다. c#에서 Boolean값은 1byte입니다.
그리고 Marshaling을 할때는 메모리 카피로 값을 카피하게 됩니다.
위에 c++구조체는 BOOL형의 4개의 변수로 구현되어 있기 때문에 16 byte입니다.
그리고 c# 구조체는 같은 이유로 4byte입니다. 스택 오버 플로우는 발생하지 않지만 값이 정상적으로 전달되지 않습니다.
예를 들면 c++에서 bA = TRUE, bB = FALSE, bC = TRUE, bD = FALSE 이런식으로 설정했다고 칩시다.
하지만 C#에서 받으면 bA = TRUE, bB = FALSE, bC = FALSE, bD = FALSE 이런식으로 받아지게 됩니다. 메모리 카피니깐요.
해결책은 쉽지요;; c++의 구조체를 바꾸던지, c#의 구조체를 바꾸던지(Boolean이 아닌 int형으로).
결과적으로 정리해봅시다.
C++(BOOL) = 4byte
C++(bool) = 1btype
C#(int) = 4byte
C#(Boolean) = 1byte
이런 식으로 통일해주시기 바랍니다.
끝!
'Programming > Tips' 카테고리의 다른 글
[윈도우] 멀티바이트와 유니코드(UTF-16, UTF-8) (1) | 2018.01.23 |
---|---|
C#소스 -> VB.NET 소스 변경 (0) | 2014.09.26 |