DEV/.Net
WinAPI 보호된 메모리를 읽거나 쓰려고 했습니다.
F.R.I.D.A.Y.
2022. 4. 6. 01:54
반응형
C#에서 WinAPI로 뭔가를 하려고 했더니 보호된 메모리라고 예외를 뱉는다.
사용하려던 Windows API는
GetWindowText(HWND hWnd, LPSTR lpstring, int nMaxCount);
그래서 C# 코드는 이렇게 했었다.
[DllImport("user32.dll", SetLastError = false)]
public static extern int GetWindowText(IntPtr hWnd, out StringBuilder lpText, in int maxCount = 256);
// ...
StringBuilder windowTitle = new StringBuilder(256);
wa.GetWindowText(hWnd, out windowTitle, windowTitle.Length+1);
근데 상단 이미지처럼 오류가 나는게 아닌가? 이리 검색해보고 저리 검색해보고 해서 결국 out 키워드를 빼봤는데 오류 없이 제대로 동작하더라.
아마도 out 키워드를 넣으면서 네이티브에서 값을 넣었는지 안 넣었는지 .NET이 파악을 못하니 오류를 토해내는게 아닌가 싶다.
자세한 건 알아봐야겠지만..
++
위 코드로 작성하면 당장 문제는 없어도 타이틀을 못 가져온다.
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpText, int maxCount = 256);
CharSet = CharSet.Auto 를 꼭 넣어주어야 한다. 안그러면 오류나서 제대로 못 가져옴. 이유를 생각해보니, WinAPI에는 _A와 _W 함수로 두개가 있는데 이걸 #define GetWindowText로 wrapping 시켜놨다. 즉, 유니코드 타입의 개발이던 ASCII 타입의 개발이던 그에 맞춰서 전처리 선언으로 래핑시켜버리는 것. 그러나 C#에는 그런게 없으니, 함수를 호출할 때 캐릭터셋을 알아서 맞춰달라고 명시해주어야 하는 듯 하다.
728x90
반응형